React onClick-通过事件传递参数


99

没有参数

function clickMe(e){
  //e is the event
}

<button onClick={this.clickMe}></button>

带参数

function clickMe(parameter){
  //how to get the "e" ?
}
<button onClick={() => this.clickMe(someparameter)}></button>

我想得到event。我怎么才能得到它?

Answers:


178

尝试这个:

<button onClick={(e) => {
     this.clickMe(e, someParameter)
}}>Click Me!</button>

并在您的职能:

function clickMe(event, someParameter){
     //do with event
}

3
这给了我一个eslint错误(eslint.org/docs/rules/arrow-parens.html)我所做的是将函数参数包装在括号内onClick={(e) => { this.clickMe(e, someparameter) }}
kretzm

1
是@kretzm如果不给出括号,则当它为单行时它会作为返回表达式,否则我们必须使用括号将其包装为函数体。
Jyothi Babu Araja

4
我只想补充一点,这是不建议使用的语法。来自reactjs文档:这种语法的问题是,每次渲染按钮时都会创建一个不同的回调。在大多数情况下,这很好。但是,如果将此回调作为对较低组件的支持传递,则这些组件可能会进行额外的重新渲染。我们通常建议在构造函数中进行绑定或使用类字段语法进行绑定,以避免此类性能问题。更多信息,请访问reactjs.org
Northernwind

1
@胜利者。是的,你是对的。但是,如果要在回调中包含父级的上下文,则需要在每个渲染器上使用不同的回调。我认为这实际上是一个折衷。
Jyothi Babu Araja

@JyothiBabuAraja我认为最好的解决方案是利用data-*HTML5中的属性。请参阅以下我的答案以获取更多详细信息。
哈里·张

38

使用ES6,您可以像这样更短地进行操作:

const clickMe = (parameter) => (event) => {
    // Do something
}

并使用它:

<button onClick={clickMe(someParameter)} />

这是否还解决了创建新的回调问题?stackoverflow.com/questions/42597602/...
大谷酒造

1
除此之外,您还可以发送多个参数。const clickMe =(parameter1,parameter2)=>(事件)=> {//做某事}
AhuraMazda

1
安装组件时也会触发此代码,您的代码应为:onClick={(e) => clickMe(someParameter)(e)}
Alexander Kim'2

类似于clickMe,即使您未将其定义为参数,您也可以销毁该事件。
Minh Kha

谢谢你 有用。但是为什么会有const clickMe = (parameter) => (event) => {...} 替代品const clickMe = (parameter) => {...}呢?
zrna

17

解决方案1

function clickMe(parameter, event){
}

<button onClick={(event) => {this.clickMe(someparameter, event)}></button>

解决方案2解决方案1中,使用绑定函数比使用箭头函数更好。请注意,事件参数应该是处理函数中的最后一个参数。

function clickMe(parameter, event){
}

<button onClick={this.clickMe.bind(this, someParameter)}></button>

事件参数+1是解决方案2中的最后一件事。永远让我意识到我做错了什么,我一定错过了文档中某个地方的原因。
abelito

5

要完全解决创建新的回调问题,利用data-*HTML5中的属性是IMO的最佳解决方案。从一天开始,即使您提取了一个子组件来传递参数,它仍然会创建新功能。

例如,

const handleBtnClick = e => {
  const { id } = JSON.parse(e.target.dataset.onclickparam);
  // ...
};

<button onClick={handleBtnClick} data-onclickparam={JSON.stringify({ id: 0 })}>

有关使用属性的信息,请参见https://developer.mozilla.org/en-US/docs/Learn/HTML/Howto/Use_data_attributesdata-*


我喜欢这种方法。简单干净
marknt15

5

柯里用ES6例如:

const clickHandler = param => event => {
  console.log(param); // your parameter
  console.log(event.type); // event type, e.g.: click, etc.
};

我们的按钮,切换处理程序:

<button onClick={(e) => clickHandler(1)(e)}>Click me!</button>

如果要在没有事件对象的情况下调用此函数表达式,则可以通过以下方式调用它:

clickHandler(1)();

另外,由于react使用合成事件(本机事件的包装器),因此存在事件池,这意味着,如果要event异步使用对象,则必须使用event.persist()

const clickHandler = param => event => {
  event.persist();
  console.log(event.target);
  setTimeout(() => console.log(event.target), 1000); // won't be null, otherwise if you haven't used event.persist() it would be null.
};

这是一个实时示例:https : //codesandbox.io/s/compassionate-joliot-4eblc?fontsize=14&hidenavigation=1&theme=dark


为什么我仍然需要event.persist()与之console.log(event)共存,但我却不需要console.log(event.target)
艾萨克·朴


在这种情况下,使用正常函数接收2个参数要比currying更快。您可以在jsben.ch中运行基准测试
ncesar

@ncesar您如何在jsben.ch中设置React?发布您的测试PLZ。
艾萨克·朴

@IsaacPak jsben是测试javascript代码的简单工具。您几乎放置了两个不同的代码示例,并比较了它们的速度。您不必放入整个React代码,而只是放一个您认为可能会更慢并且要测试的函数。另外,我总是使用jsben.ch和jsbench.me只是为了确保。在clickHandler上下文中,您需要模拟一些代码。像let event;这样,它不会引发未定义的错误。
ncesar
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.