【问题标题】:Why is my onClick being called on render? - React.js为什么我的 onClick 在渲染时被调用? - React.js
【发布时间】:2016-03-17 12:23:15
【问题描述】:

我创建了一个组件:

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);

当我render 这个页面时,activatePlaylist 会为我的map 中的每个playlist 调用。如果我bind activatePlaylist 喜欢:

activatePlaylist.bind(this, playlist.playlist_id)

我也可以使用匿名函数:

onClick={() => this.activatePlaylist(playlist.playlist_id)}

然后它按预期工作。为什么会这样?

【问题讨论】:

    标签: javascript reactjs redux


    【解决方案1】:
    import React from 'react';
    import { Page ,Navbar, Popup} from 'framework7-react';
    
    class AssignmentDashboard extends React.Component {
        constructor(props) {
          super(props);
          this.state = {
    
        }
    
        
          onSelectList=(ProjectId)=>{
              return(
    
                console.log(ProjectId,"projectid")
              )
    
          }
                
    render() {
           
        return (   
          
     <li key={index} onClick={()=> this.onSelectList(item.ProjectId)}></li>
                           
                           )}
    

    【讨论】:

    • 您能否添加一些解释而不是仅发布一些代码?它确实会提高您的答案的质量
    【解决方案2】:

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

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

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

    2.
    onClick={ (event) => { this.activatePlaylist.(playlist.playlist_id)}}
    

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

    【讨论】:

      【解决方案3】:

      我知道这篇文章已经有几年了,但只是为了参考来自https://reactjs.org/tutorial/tutorial.html 的关于这个常见错误(我也犯过)的最新 React 教程/文档:

      注意

      为了节省打字并避免这种混乱行为,我们将使用 此处和下方的事件处理程序的箭头函数语法:

      class Square extends React.Component {
       render() {
         return (
           <button className="square" onClick={() => alert('click')}>
             {this.props.value}
           </button>
         );
       }
      }
      

      注意 onClick={() => alert('click')},我们传递了一个 用作 onClick 道具。 React 只会在之后调用这个函数 点击一下。忘记 () => 并写 onClick={alert('click')} 是 常见错误,并且每次组件都会触发警报 重新渲染。

      【讨论】:

        【解决方案4】:

        你需要传递给onClick reference 来运行,当你这样做时activatePlaylist( .. ) 你调用函数并传递给onClickactivatePlaylist 返回的值。您可以使用以下三个选项之一:

        1。使用.bind

        activatePlaylist.bind(this, playlist.playlist_id)
        

        2。使用箭头函数

        onClick={ () => this.activatePlaylist(playlist.playlist_id) }
        

        3。或从activatePlaylist返回函数

        activatePlaylist(playlistId) {
          return function () {
             // you code 
          }
        }
        

        【讨论】:

        • 我不记得它在以前版本的React 中是这样工作的。是我记错了还是api 变了?
        • @jhamm 您正在使用 ES6 类,在这种情况下您应该手动绑定上下文。
        • @AlexanderT。有一件事我不明白。如果你用.bind绑定上下文,如你在步骤1中所说,有必要做步骤2吗?如果是,为什么?因为我认为当你使用箭头函数时,上下文就是定义函数的地方,但是如果我们使用.bind附加上下文,上下文已经附加了,对吧?
        • @Rafa Romero 这只是三个不同的选项,您可以使用其中之一
        • React Docs 官方网站上现在有一个版块对这个问题进行了全面的回答:reactjs.org/docs/faq-functions.html
        【解决方案5】:

        当 React 宣布发布基于类的组件时,记录了这种行为。

        https://facebook.github.io/react/blog/2015/01/27/react-v0.13.0-beta-1.html

        自动绑定

        React.createClass 有一个内置的魔法特性,可以自动为你绑定所有方法。对于不习惯在其他类中使用此功能的 JavaScript 开发人员来说,这可能会有些混乱,或者当他们从 React 转移到其他类时可能会感到困惑。

        因此我们决定不将这个内置到 React 的类模型中。如果需要,您仍然可以在构造函数中显式预绑定方法。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2014-08-17
          • 2021-08-26
          • 1970-01-01
          • 2023-03-24
          • 1970-01-01
          • 1970-01-01
          • 2017-10-15
          相关资源
          最近更新 更多