为啥我的 onClick 在渲染时被调用? - React.js

Posted

技术标签:

【中文标题】为啥我的 onClick 在渲染时被调用? - React.js【英文标题】: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)

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

【问题讨论】:

【参考方案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 的类模型中。如果需要,您仍然可以在构造函数中显式预绑定方法。

【讨论】:

以上是关于为啥我的 onClick 在渲染时被调用? - React.js的主要内容,如果未能解决你的问题,请参考以下文章

a href onClick 在页面启动时被调用(在点击链接之前)

为啥我的 TabBar 按钮在我第一次加载视图控制器时被禁用?

为啥 bootstrap-vue 不渲染 onclick?

在 onClick 函数中调用更新函数时 useState 不会重新渲染

如果我们应用类型擦除,哪些重载方法将在运行时被调用,为啥?

React:每次渲染都会调用 onClick 处理程序?