Monday, May 20, 2024
 Popular · Latest · Hot · Upcoming
140
rated 0 times [  146] [ 6]  / answers: 1 / hits: 16482  / 8 Years ago, mon, january 2, 2017, 12:00:00

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.


More From » reactjs

 Answers
19

I think you have a typo in this line:



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


It should be:



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


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


[#59494] Thursday, December 29, 2016, 8 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
makaylahk

Total Points: 166
Total Questions: 94
Total Answers: 117

Location: Gabon
Member since Sat, Jul 25, 2020
4 Years ago
;