【问题标题】:Binding event handlers in React Components fires onClick when renderedReact 组件中的绑定事件处理程序在渲染时触发 onClick
【发布时间】:2017-02-03 04:14:36
【问题描述】:

我正在学习 React。在我正在编写的测试应用程序中,我正在使用 onClick 方法呈现一些按钮。当它们像这样呈现时,它们会在单击时按预期工作并调用 selectMode 函数。

constructor(props) {
    super(props);
    this.state = { mode: 'commits', commits: [], forks: [], pulls: [] };
}    
...
selectMode(mode) {
    this.setState({ mode });
}    

render() {
...
return (<div>                
        <button onClick={this.selectMode.bind(this, 'commits')}>Show Commits</button><br/>
        <button onClick={this.selectMode.bind(this, 'forks')}>Show Forks</button><br/>
        <button onClick={this.selectMode.bind(this, 'pulls')}>Show Pulls</button>
        </div>
        )
}

但是当我尝试下面显示的建议的最佳实践方式时,通过在构造函数中绑定,在渲染组件时会调用 3 次 selectMode 函数。为什么会调用 onClick 事件处理程序?我有什么问题?

constructor(props) {
    super(props);
    this.state = { mode: 'commits', commits: [], forks: [], pulls: [] };
    this.selectMode = this.selectMode.bind(this)
}
...
selectMode(mode) {
    this.setState({ mode });
}

render() {
...
return (<div>                
        <button onClick={this.selectMode('commits')}>Show Commits</button><br/>
        <button onClick={this.selectMode('forks')}>Show Forks</button><br/>
        <button onClick={this.selectMode('pulls')}>Show Pulls</button>
        </div>
        )
} 

【问题讨论】:

    标签: reactjs event-handling


    【解决方案1】:

    您的this.selectMode(...) 会在您的组件被渲染时立即执行。

    <.. onClick={this.selectMode('commits')}..../> <-- function is called immediately
    

    您可以使用arrow function 创建一个匿名函数,您可以在其中调用您的方法。这样,你的this.selectMode方法只会在点击事件发生时被调用:

    <.. onClick={() => this.selectMode('commits')}..../> 
    

    如果您不想在每次渲染组件时都创建匿名函数,您可以将值存储到元素的属性中。像这样:

    constructor(props) {
     super(props);
     this.state = { mode: 'commits', commits: [], forks: [], pulls: [] };
     this.selectMode = this.selectMode.bind(this)
    }
    selectMode(event){
        this.setState({mode: e.target.name});
    }
    render(){
    ....
       <.. onClick={this.selectMode} name='commits' ..../> 
    ..}
    

    【讨论】:

    • 使用元素的属性是传递这些参数的好方法。我太新了,没有想到这一点,而且我看到的没有任何例子涵盖了传递参数。
    【解决方案2】:

    我不确定,但我认为这是因为您通过添加括号来调用每个 onClick 函数。如果你使用 ES6,你可以尝试这样做:

    onClick = () => { this.selectMode('commits') }
    onClick = () => { this.selectMode('forks') }
    onClick = () => { this.selectMode('pulls') }
    

    【讨论】:

    • 是的,箭头函数使用额外的大括号,如下所示:。这在反应文档中有所介绍。但我试图不使用箭头函数。我的方法也在 React 文档中(但从未显示传递参数)。
    猜你喜欢
    • 2016-07-21
    • 2017-03-19
    • 2015-04-15
    • 2021-06-05
    相关资源
    最近更新 更多