ES6 - 警告:setState(...):在现有状态转换期间无法更新 [英] ES6 - Warning: setState(…): Cannot update during an existing state transition

查看:109
本文介绍了ES6 - 警告:setState(...):在现有状态转换期间无法更新的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在重写一些旧的ReactJS代码,并且卡住了这个错误(错误在控制台中重复约1700次,DOM根本不呈现):



< blockquote>

警告:setState(...):在现有状态下不能更新
转换(例如在 render 或另一个组件的
构造函数)。渲染方法应该是道具和
状态的纯函数;构造函数副作用是反模式,但可以将
移动到 componentWillMount


我是一个将其状态传递给应该呈现某些控件的组件的组件。基于点击的控件,状态应该更改,新的控件应该呈现。



所以这是我的容器组件:

  class TeaTimer extends Component {
constructor(props){
super(props);
this.state = {
count:120,
countdownStatus:'started'
}
}

componentDidUpdate(prevProps,prevState) {
if(this.state.countdownStatus!== prevState.countdownStatus){
switch(this.state.countdownStatus){
case'started':
this.startTimer( );
break;
case'stopped':
this.setState({count:0});
}
}
}

componentWillUnmount(){
clearInterval(this.timer);
删除this.timer;
}

startTimer(){
this.timer = setInterval(()=> {
let newCount = this.state.count -1;
this.setState({
count:newCount> = 0?newCount:0
});
if(newCount === 0){
this.setState {countdownStatus:'stopped'});
}
},1000)
}

handleStatusChange(newStatus){
this.setState({countdownStatus :newStatus});
}

render(){
let {count,countdownStatus} = this.state;
让renderStartStop =()=> {
if(countdownStatus!=='stopped'){
return< StartStop countdownStatus = {countdownStatus} onStatusChange = {this.handleStatusChange()} />
} else {
return< div>这将是滑块形式< / div>
}
};
return(
< div className = {styles.container}>
< p>这是TeaTimer组件< / p>
< Clock totalSeconds = {count } />
{renderStartStop()}
< / div>

}
}
pre>

这是我的控件组件:

  class StartStop extends组件{
构造函数(道具){
super(props);
}

onStatusChange(newStatus){
return()=> {
this.props.onStatusChange(newStatus);
}
}

render(){
let {countdownStatus} = this.props;

让renderStartStopButton =()=> {
if(countdownStatus ==='started'){
return< button onClick = {()=> this.onStatusChange(停止)}>复位< /按钮取代;
} else {
return< button onClick = {()=> this.onStatusChange(开始)}>开始< /按钮>
}
};

return(
< div className = {styles.tt.Controls}>
{renderStartStopButton()}
< / div>

}
}

StartStop.propTypes = {
countdownStatus:React.PropTypes.string.isRequired,
onStatusChange:React.PropTypes.func。 isRequired
};

我很抱歉文字墙,但我真的可以,弄清楚错误在哪里来自 - 因此不知道代码中可以省略哪一部分。



我已经尝试实现在看似相关的问题,但不能让它工作。 / p>

解决方案

我觉得你在这一行有错字:

  return< StartStop countdownStatus = {countdownStatus} onStatusChange = {this.handleStatusChange()} /> 

我应该是

  return< StartStop countdownStatus = {countdownStatus} onStatusChange = {() - > this.handleStatusChange} /> 

您似乎正在调用方法 handleStatusChange 而不是将其作为回调。


I am rewriting some old ReactJS code, and got stuck fixing this error (the error repeats about 1700 times in the console, the DOM does not render at all):

Warning: setState(...): Cannot update during an existing state transition (such as within render or another component's constructor). Render methods should be a pure function of props and state; constructor side-effects are an anti-pattern, but can be moved to componentWillMount.

I am a Component that passes it's state down to a component that should render some controls. Based on the clicked controls, the state should change, and new controls should render.

So this is my Container component:

class TeaTimer extends Component {
    constructor(props) {
        super(props);
        this.state = {
            count: 120,
            countdownStatus: 'started'
        }
    }

    componentDidUpdate(prevProps, prevState) {
        if (this.state.countdownStatus !== prevState.countdownStatus) {
            switch (this.state.countdownStatus) {
                case 'started':
                    this.startTimer();
                    break;
                case 'stopped':
                    this.setState({count:0});
            }
        }
    }

    componentWillUnmount() {
        clearInterval(this.timer);
        delete this.timer;
    }

    startTimer() {
        this.timer = setInterval(() => {
            let newCount = this.state.count -1;
            this.setState({
                count: newCount >= 0 ? newCount : 0
            });
            if(newCount === 0) {
                this.setState({countdownStatus: 'stopped'});
            }
        }, 1000)
    }

    handleStatusChange(newStatus) {
        this.setState({ countdownStatus: newStatus });
    }

    render() {
        let {count, countdownStatus} = this.state;
        let renderStartStop = () => {
            if (countdownStatus !== 'stopped') {
                return <StartStop countdownStatus={countdownStatus} onStatusChange={this.handleStatusChange()}/>
            } else {
                return <div>This will be the slider form</div>
            }
        };
        return(
            <div className={styles.container}>
                <p>This is the TeaTimer component</p>
                <Clock totalSeconds={count}/>
                {renderStartStop()}
            </div>
        )
    }
}

And this is my controls component:

class StartStop extends Component {
    constructor(props) {
        super(props);
    }

    onStatusChange(newStatus) {
        return() => {
            this.props.onStatusChange(newStatus);
        }
    }

    render() {
        let {countdownStatus} = this.props;

        let renderStartStopButton = () => {
            if(countdownStatus === 'started') {
                return <button onClick={()=> this.onStatusChange('stopped')}>Reset</button>;
            } else {
                return <button onClick={()=> this.onStatusChange('started')}>Start</button>
            }
        };

        return(
            <div className={styles.tt.Controls}>
                {renderStartStopButton()}
            </div>
        )
    }
}

StartStop.propTypes = {
    countdownStatus: React.PropTypes.string.isRequired,
    onStatusChange: React.PropTypes.func.isRequired
};

I am sorry about the wall of text, but I really can;t figure out where the error is coming from - and therefor don't know which part of the code I can leave out.

I have tried implementing the solution found in a seemingly related question, but can't get it to work either.

解决方案

I think you have a typo in this line:

return <StartStop countdownStatus={countdownStatus} onStatusChange={this.handleStatusChange()}/>

I should be

return <StartStop countdownStatus={countdownStatus} onStatusChange={() -> this.handleStatusChange}/>

You seem to be calling the method handleStatusChange instead of passing it as a callback.

这篇关于ES6 - 警告:setState(...):在现有状态转换期间无法更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆