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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 16:04:33  来源:igfitidea点击:

Why is my onClick being called on render? - React.js

javascriptreactjsredux

提问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 renderthis page, activatePlaylistis called for each playlistin my map. If I bindactivatePlaylistlike:

当我render这个页面,activatePlaylist被每一个信息playlist在我的map。如果我bindactivatePlaylist喜欢:

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 onClickreferenceto function, when you do like this activatePlaylist( .. )you call function and pass to onClickvalue that returned from activatePlaylist. You can use one of these three options:

您需要传递对函数的onClick引用,当您这样做时,activatePlaylist( .. )您调用函数并传递给onClickactivatePlaylist. 您可以使用以下三个选项之一:

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 onClickevent. Follow one of the below-mentioned implementation to resolve your problem.

您传递方法的方式this.activatePlaylist(playlist.playlist_id)将立即调用该方法。您应该将方法的引用传递给onClick事件。按照下面提到的实现之一来解决您的问题。

1.
onClick={this.activatePlaylist.bind(this,playlist.playlist_id)}

Here bind property is used to create a reference of the this.activatePlaylistmethod by passing thiscontext and argument playlist.playlist_id

这里的 bind 属性用于this.activatePlaylist通过传递this上下文和参数来创建方法的引用playlist.playlist_id

2.
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.activatePlaylistmethod will be called.

这会将一个函数附加到 onClick 事件,该函数将仅在用户单击操作时触发。当此代码执行时,this.activatePlaylist将调用该方法。