Javascript React.js 中的 OnClick 事件绑定
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/27397266/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
OnClick Event binding in React.js
提问by Swaraj Ghosh
I would like to pass the parent divid, on click of that div or any child element of the same div. But I am unable to achieve it. Please tell me where I am making a mistake. Code is below:
我想通过div单击该 div 或相同div. 但我无法实现它。请告诉我我哪里出错了。代码如下:
viewMore: function(i,j){
console.log('You clicked: ', i );
},
render : function(){
var attributeId = "groups_";
attributeId+= index;
return(
//parent div
<div className="groups" id={attributeId} onClick={this.viewMore}>
<div className="floatLeft"> Group Name: <h3>My Name</h3></div>
<span className="floatRight typeCd">POC</span>
<div className="clearfix"> Key Attributes:
<ul>
<li> POC 1</li>
</ul>
</div>
</div>
)
};
回答by Henrik Andersson
viewMore = (i,j) => () => {
console.log(i,j)
}
To pass parameters to event handlers we need to use currying. With the above method no new functions created all the time while render is called.
要将参数传递给事件处理程序,我们需要使用currying。使用上述方法,在调用 render 时不会一直创建新函数。
回答by ZenMaster
Since I see these kind of suggestions in multiple places, I am going to move my comment into an answer as well, to provide an additional view:
由于我在多个地方看到此类建议,因此我也将把我的评论移到答案中,以提供额外的观点:
class TestComponent extends React.Component {
constructor() {
super();
this.onClick = this.handleClick.bind(this);
}
handleClick(event) {
const {id} = event.target;
console.log(id);
}
render() {
return (
<div>
<h3 id={this.props.id} onClick={this.onClick}>
{this.props.name}
</h3>
</div>
);
}
}
This allows to:
这允许:
- avoid unnecessary binds
- access the
idand whatever else properties in a much more React-ive manner.
- 避免不必要的绑定
id以更具反应性的方式访问 the和其他任何属性。
Of course, the above example assumes that you receive the idas a prop, but you can do the necessary manipulations as well.
当然,上面的例子假设你收到了id一个 prop,但你也可以做一些必要的操作。
UPDATE 1 -- Nov 28, 2016
更新 1 -- 2016 年 11 月 28 日
Added link to CodePenfrom comments above.
添加了来自上述评论的CodePen链接。
UPDATE 2 -- Mar 30, 2017
更新 2 -- 2017 年 3 月 30 日
As mentioned, this wouldn't work if you use React.createClassto define your components. You don't have a constructor to pull this off. You can use other lifecycle methods, if you don't mind a little ugliness.
如前所述,如果您React.createClass用来定义组件,这将不起作用。你没有一个构造函数来实现它。如果您不介意有点丑陋,您可以使用其他生命周期方法。
Having said that, it is 2017. Use ES6, would you?!
话虽如此,现在是 2017 年。使用 ES6,你会吗?!
UPDATE 3 -- May 12, 2017
更新 3 -- 2017 年 5 月 12 日
If you are using class properties transform, then you can simplify it further:
如果您使用的是类属性 transform,那么您可以进一步简化它:
class TestComponent extends React.Component {
onClick = (event) => {
const {id} = event.target;
console.log(id);
}
render() {
return (
<div>
<h3 id={this.props.id} onClick={this.onClick}>
{this.props.name}
</h3>
</div>
);
}
}
UPDATE 4 -- Feb 4, 2018
更新 4 -- 2018 年 2 月 4 日
Due to improvements of bindand friends in V8 (Chakra and such probably too), you just may be better off using the this.click.bind(this)or wrapping it in an arrow function when passing to onClick.
由于bindV8 中的和朋友的改进(Chakra 等可能也是如此),您最好this.click.bind(this)在传递给onClick.
Why?
为什么?
The previous method, created for performance reasons only, closed some possibilities for dynamically injecting functions onto the component's prototype.
之前创建的方法只是出于性能原因,关闭了将函数动态注入组件原型的一些可能性。
NOTE 1 -- Apr 14, 2018
注 1——2018 年 4 月 14 日
Keep in mind that the method mentioned in Update 4 still introduces some performance issues, as on each renderpass a new function is created as a result of bind. This, in turn, will trickle down to the child component and cause unnecessary re-renders, as the function changes each time.
请记住,更新 4 中提到的方法仍然引入了一些性能问题,因为在每次render传递时都会创建一个新函数作为bind. 反过来,这将渗透到子组件并导致不必要的重新渲染,因为函数每次都在变化。
The same thing happens when you pass an arrow function inline.
当您内联传递箭头函数时,也会发生同样的事情。
All other methods, like using class properties, will mess with your inheritance (which you should be avoiding, but still), simply due to the fact that, currently, Babel transpiles them to "on-instance" functions, which are not on the prototype chain.
所有其他方法,比如使用类属性,都会干扰你的继承(你应该避免,但仍然如此),仅仅是因为目前 Babel 将它们转换为“实例上”函数,这些函数不在原型链。
So, this:
所以这:
class Person {
printA = () => { console.log('a') }
}
becomes:
变成:
function _classCallCheck(instance, Constructor) {...abridged...}
var Person = function Person() {
_classCallCheck(this, Person);
this.printA = function () {
console.log('a');
};
};
回答by aikeru
I've made an updated answer for ES6 here: https://stackoverflow.com/a/35748912/76840
我在这里为 ES6 做了一个更新的答案:https://stackoverflow.com/a/35748912/76840
Essentially, you can use arrow function expressions, which have the benefit of preserving this:
本质上,您可以使用箭头函数表达式,它具有保留 的好处this:
onClick={(event)=>this.viewMore(attributeId, event)}
As of this edit, if you're using Babel with stage-2 enabled, you can use a property like so:
在此编辑中,如果您使用启用了第 2 阶段的 Babel,您可以使用如下属性:
// Within your class...
viewMore = (event) => { /* ... */ }
// Within render method in your JSX
onClick = {this.viewMore}
回答by Sagiv b.g
You can use curryingfunction.
您可以使用柯里化功能。
ES5:
ES5:
viewMore(param) { // param is the argument you passed to the function
return function(e) { // e is the event object that returned
};
}
ES6
ES6
viewMore = param => e => {
// param is the argument you passed to the function
// e is the event object that returned
};
And just use it like this:
就像这样使用它:
onClick={this.viewMore("some param")}
回答by roshan
Here is an update and an overview of previous answers:
以下是先前答案的更新和概述:
- Using onClick={this.viewMore.bind(this, attributeId)} by @HenrikAndersson.While this approach serves the purpose it uses the bind syntax with which many are not comfortable.
Using public class fieldmentioned by @ZenMaster.This solution has more or less the same performance, it also comes with a better syntax. But it turns tricky when we have to pass a parameter.
class TestComponent extends React.Component { onClick = (event) => { const {id} = event.target; console.log(id); } render() { return ( <div> <h3 id={this.props.id} onClick={this.onClick}> {this.props.name} </h3> </div> ); } }
- 通过使用的onClick = {this.viewMore.bind(此,属性Id)} @HenrikAndersson。而这种方法提供它使用的绑定的语法与许多不舒服的目的。
使用@ZenMaster提到的公共类字段。这个解决方案或多或少具有相同的性能,它还带有更好的语法。但是当我们必须传递一个参数时就变得很棘手了。
class TestComponent extends React.Component { onClick = (event) => { const {id} = event.target; console.log(id); } render() { return ( <div> <h3 id={this.props.id} onClick={this.onClick}> {this.props.name} </h3> </div> ); } }
The above mentioned approach skips passing parameters and instead uses custom attributes to access the data required in click handler.
上面提到的方法跳过传递参数,而是使用自定义属性来访问点击处理程序中所需的数据。
A better solution would be :
更好的解决方案是:
class MyComponent extends React.Component {
handleClick = (item) => (e) => {
e.preventDefault()
console.log(`This has access to item ${item}! and event(e)`)
}
render(){
const item={ id:'1', value: 'a' }
return(
<button onClick={ this.handleClick(item) } >Click</button>
)
}
}

