我正在重写一些旧的ReactJS代码,并且无法修复此错误(错误在控制台中重复约1700次,DOM根本不会渲染):
警告:setState(...):在现有状态期间无法更新 过渡(例如在
render
或其他组件内 构造函数)。渲染方法应该是道具的纯函数 州;构造函数的副作用是反模式,但可以移动 到componentWillMount
。
我是一个组件,它将状态传递给应该呈现某些控件的组件。根据单击的控件,状态应该更改,并且应该呈现新控件。
所以这是我的Container组件:
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>
)
}
}
这是我的控制组件:
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
};
我很抱歉文字的墙,但我真的可以;弄清楚错误的来源 - 因此不知道我可以省略哪部分代码。
我已尝试实施seemingly related question中找到的解决方案,但无法使其正常运行。
答案 0 :(得分:7)
我认为你在这一行中有一个错字:
return <StartStop countdownStatus={countdownStatus} onStatusChange={this.handleStatusChange()}/>
应该是:
return <StartStop countdownStatus={countdownStatus} onStatusChange={() => this.handleStatusChange}/>
您似乎在调用方法handleStatusChange
,而不是将其作为回调传递。
答案 1 :(得分:0)
你的metods互相调用,所以你必须定义两个你的metods实例。
class StartStop extends Component {
constructor(props) {
super(props);
this.onStatusChangeReset=this.onStatusChange.bind(this);
this.onStatusChangeStart=this.onStatusChange.bind(this);
}
onStatusChange(newStatus) {
return() => {
this.props.onStatusChange(newStatus);
}
}
render() {
let {countdownStatus} = this.props;
let renderStartStopButton = () => {
if(countdownStatus === 'started') {
return <button onClick={this.onStatusChangeReset('stopped')}>Reset</button>;
} else {
return <button onClick={this.onStatusChangeStart('started')}>Start</button>
}
};
return(
<div className={styles.tt.Controls}>
{renderStartStopButton()}
</div>
)
}
}
StartStop.propTypes = {
countdownStatus: React.PropTypes.string.isRequired,
onStatusChange: React.PropTypes.func.isRequired
};
答案 2 :(得分:-1)
在return <StartStop countdownStatus={countdownStatus} onStatusChange={this.handleStatusChange()}/>
的这一行给出警告,按下一个试图通过setState关键字改变状态的按钮时调用handleStatusChanged函数。每当状态改变时,再次调用渲染函数,但在你的情况下渲染函数正在返回,而setState关键字再次调用渲染函数。