Javascript 为什么我的 onClick 在渲染时被调用?- 反应.js
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/34226076/
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
Why is my onClick being called on render? - React.js
提问by jhamm
I have a component that I have created:
我有一个我创建的组件:
class Create extends Component {
constructor(props) {
super(props);
}
render() {
var playlistDOM = this.renderPlaylists(this.props.playlists);
return (
<div>
{playlistDOM}
</div>
)
}
activatePlaylist(playlistId) {
debugger;
}
renderPlaylists(playlists) {
return playlists.map(playlist => {
return <div key={playlist.playlist_id} onClick={this.activatePlaylist(playlist.playlist_id)}>{playlist.playlist_name}</div>
});
}
}
function mapStateToProps(state) {
return {
playlists: state.playlists
}
}
export default connect(mapStateToProps)(Create);
When I render
this page, activatePlaylist
is called for each playlist
in my map
. If I bind
activatePlaylist
like:
当我render
这个页面,activatePlaylist
被每一个信息playlist
在我的map
。如果我bind
activatePlaylist
喜欢:
activatePlaylist.bind(this, playlist.playlist_id)
I can also use an anonymous function:
我还可以使用匿名函数:
onClick={() => this.activatePlaylist(playlist.playlist_id)}
then it works as expected. Why does this happen?
然后它按预期工作。为什么会发生这种情况?
回答by Alexander T.
You need pass to onClick
referenceto function, when you do like this activatePlaylist( .. )
you call function and pass to onClick
value that returned from activatePlaylist
. You can use one of these three options:
您需要传递对函数的onClick
引用,当您这样做时,activatePlaylist( .. )
您调用函数并传递给onClick
从activatePlaylist
. 您可以使用以下三个选项之一:
1. using .bind
1. 使用.bind
activatePlaylist.bind(this, playlist.playlist_id)
2. using arrow function
2. 使用箭头函数
onClick={ () => this.activatePlaylist(playlist.playlist_id) }
3. or return function from activatePlaylist
3. 或返回函数activatePlaylist
activatePlaylist(playlistId) {
return function () {
// you code
}
}
回答by David L. Walsh
This behaviour was documented when React announced the release of class based components.
当 React 宣布发布基于类的组件时,记录了这种行为。
https://facebook.github.io/react/blog/2015/01/27/react-v0.13.0-beta-1.html
https://facebook.github.io/react/blog/2015/01/27/react-v0.13.0-beta-1.html
Autobinding
React.createClass has a built-in magic feature that bound all methods to this automatically for you. This can be a little confusing for JavaScript developers that are not used to this feature in other classes, or it can be confusing when they move from React to other classes.
Therefore we decided not to have this built-in into React's class model. You can still explicitly prebind methods in your constructor if you want.
自动绑定
React.createClass 有一个内置的魔法特性,可以自动为你绑定所有方法。对于不习惯其他类中的此功能的 JavaScript 开发人员来说,这可能会有点混乱,或者当他们从 React 转移到其他类时可能会感到困惑。
因此我们决定不将这个内置到 React 的类模型中。如果需要,您仍然可以在构造函数中显式地预绑定方法。
回答by CAM_344
I know this post is a few years old already, but just to reference the latest React tutorial/documentation about this common mistake (I made it too) from https://reactjs.org/tutorial/tutorial.html:
我知道这篇文章已经有几年了,但只是为了从https://reactjs.org/tutorial/tutorial.html引用关于这个常见错误的最新 React 教程/文档(我也犯了):
Note
To save typing and avoid the confusing behavior of this, we will use the arrow function syntax for event handlers here and further below:
笔记
为了节省输入并避免这种令人困惑的行为,我们将在此处和下面的事件处理程序中使用箭头函数语法:
class Square extends React.Component {
render() {
return (
<button className="square" onClick={() => alert('click')}>
{this.props.value}
</button>
);
}
}
Notice how with onClick={() => alert('click')}, we're passing a function as the onClick prop. React will only call this function after a click. Forgetting () => and writing onClick={alert('click')} is a common mistake, and would fire the alert every time the component re-renders.
注意 onClick={() => alert('click')} 是如何传递一个函数作为 onClick 属性的。React 只会在点击后调用这个函数。忘记 () => 并编写 onClick={alert('click')} 是一个常见的错误,每次组件重新渲染时都会触发警报。
回答by Shrishail Uttagi
The way you passing the method this.activatePlaylist(playlist.playlist_id)
, will call the method immediately. You should pass the reference of the method to the onClick
event. Follow one of the below-mentioned implementation to resolve your problem.
您传递方法的方式this.activatePlaylist(playlist.playlist_id)
将立即调用该方法。您应该将方法的引用传递给onClick
事件。按照下面提到的实现之一来解决您的问题。
onClick={this.activatePlaylist.bind(this,playlist.playlist_id)}
Here bind property is used to create a reference of the this.activatePlaylist
method by passing this
context and argument playlist.playlist_id
这里的 bind 属性用于this.activatePlaylist
通过传递this
上下文和参数来创建方法的引用playlist.playlist_id
onClick={ (event) => { this.activatePlaylist.(playlist.playlist_id)}}
This will attach a function to the onClick event which will get triggered on user click action only. When this code exectues the this.activatePlaylist
method will be called.
这会将一个函数附加到 onClick 事件,该函数将仅在用户单击操作时触发。当此代码执行时,this.activatePlaylist
将调用该方法。