【问题标题】:Cannot update during an existing state transition error in React在 React 中的现有状态转换错误期间无法更新
【发布时间】:2017-10-16 00:16:20
【问题描述】:

在我的渲染 return() 中,我有这些:

<button onClick={ this.selectTimeframe('Today') }
        className={ this.setActiveIf('Today') } type="button">Today</button>

这个函数是什么:

selectTimeframe(timeframe) {
    // this.setState({ timeframe });
}

^ 我现在必须注释掉 setState 否则我会收到我在上面发布的错误并且应用程序中断。

我的构造函数中有这个:

this.selectTimeframe = this.selectTimeframe.bind(this);

我找到了这个answer here,但这没有意义,我应该如何传递变量?还是他说每个独特的按钮都需要独特的功能?为了避免在渲染内部调用它?

完整代码

import React from 'react';

export class TimeframeFilter extends React.Component {

    constructor(props) {
        super(props);

        this.state = {
            timeframe: 'Today'
        };

        this.selectTimeframe = this.selectTimeframe.bind(this);
        this.setActiveIf = this.setActiveIf.bind(this);
    }

    componentDidMount() {
        console.log('%c TimeframeFilter componentDidMount', 'background: #393939; color: #bada55', this.state);
    }

    selectTimeframe(timeframe) {
        // this.setState({ timeframe });
    }

    setActiveIf(timeframe) {
        return this.state.timeframe === timeframe ? 'btn btn-default active' : 'btn btn-default';
    }

    render() {
        return (
            <div className="fl">
                <span className="label label-default mr10">Timeframe</span>
                <div className="btn-group btn-group-sm mr20" role="group">
                    <button onClick={ this.selectTimeframe('Today') }
                            className={ this.setActiveIf('Today') } type="button">Today</button>
                    <button onClick={ this.selectTimeframe('Week') }
                            className={ this.setActiveIf('Week') } type="button">Week</button>
                    <button onClick={ this.selectTimeframe('Month') }
                            className={ this.setActiveIf('Month') } type="button">Month</button>
                    <button onClick={ this.selectTimeframe('Year') }
                            className={ this.setActiveIf('Year') } type="button">Year</button>
                    <button onClick={ this.selectTimeframe('All') }
                            className={ this.setActiveIf('All') } type="button">All</button>
                </div>
            </div>
        );
    }
}

export default TimeframeFilter;

【问题讨论】:

    标签: javascript reactjs jsx


    【解决方案1】:

    您应该使用arrow function or bind method 将值传递给onClick 函数,否则它只会在每次重新渲染发生时执行以将值返回给onClick,如果您在其中使用setState,它将调用rerender以及再次调用的功能,从而重复该过程。

    这样做

    <button onClick={ ()=> this.selectTimeframe('Today') }
            className={ this.setActiveIf('Today') } type="button">Today</button>
    

    <button onClick={ this.selectTimeframe.bind(this, 'Today') }
            className={ this.setActiveIf('Today') } type="button">Today</button>
    

    希望我能够清楚地向您解释。 :)

    编辑:虽然上述方法解决了问题,但由于性能原因并不是最佳方法。我们应该避免在 render 中绑定方法,因为在重新渲染期间它会创建新方法而不是使用旧方法,这会影响性能。

    How to avoid binding inside the render method

    上查看此答案

    【讨论】:

    • 谢谢,我现在明白了……我每次都在调用这个函数。 () =&gt; 解决了这个问题。
    • 很高兴,我能够正确解释,:)
    【解决方案2】:

    目前您在渲染方法中调用this.selectTimeframe('Today')。 你可能想要

    onClick={() =&gt; this.selectTimeframe('Today') }

    或者更聪明的方式

    <button onClick={ this.selectTimeframe.bind(this, 'Today') } className={ this.setActiveIf('Today') } type="button">Today</button>
    
    selectTimeframe.bind(key) {
      switch(key){
        case 'Today':
          //your logic
          break;
      }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-04-05
      • 1970-01-01
      • 2023-03-13
      • 2016-03-31
      • 1970-01-01
      • 2017-05-31
      • 2017-01-05
      相关资源
      最近更新 更多