在 React 中的现有状态转换错误期间无法更新

IT技术 javascript reactjs jsx
2021-05-20 14:38:52

在我的渲染 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);

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

完整代码

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;
2个回答

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

做喜欢

<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 内部绑定方法,因为在重新渲染期间它会创建新方法而不是使用旧方法,这会影响性能。

请参阅有关如何避免在渲染方法内绑定的答案

当前,您调用this.selectTimeframe('Today')了渲染方法。你可能想要

onClick={() => 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;
  }
}