Andrew Andrew - 3 days ago 4
Javascript Question

React.js having state based on other state

I'm running into some problems with React.js and the state not being immediately set when calling setState(). I'm not sure if there are better ways to approach this, or if it really is just a shortcoming of React. I have two state variables, one of which is based on the other. (Fiddle of original problem: http://jsfiddle.net/kb3gN/4415/ you can see in the logs that it's not set right away when you click the button)

setAlarmTime: function(time) {
this.setState({ alarmTime: time });
this.checkAlarm();
},
checkAlarm: function() {
this.setState({
alarmSet: this.state.alarmTime > 0 && this.state.elapsedTime < this.state.alarmTime
});
}, ...


When calling
setAlarmTime
, since
this.state.alarmTime
isn't updated immediately, the following call to
checkAlarm
sets
alarmSet
based on the previous value of
this.state.alarmTime
and is therefore incorrect.

I solved this by moving the call to
checkAlarm
into the callback of
setState
in
setAlarmTime
, but having to keep track of what state is actually 'correct' and try to fit everything into callbacks seems ridiculous:

setAlarmTime: function(time) {
this.setState({ alarmTime: time }, this.checkAlarm);
}


Is there a better way to go about this? There are a few other places in my code which I reference state I just set and now I'm unsure as to when I can actually trust the state!

Thanks

Answer

Yes, setState is asynchronous, so this.state won't be updated immediately. Here are the unit tests for batching, which might explain some of the details.

In the example above, alarmSet is data computed from the alarmTime and elapsedTime state. Generally speaking, computed data shouldn't be stored in the state of the object, instead it should be computed as-needed as part of the render method. There is a section What Shouldn’t Go in State? at the bottom of the Interactivity and Dynamic UIs docs which gives examples of things like this which shouldn't go in state, and the What Components Should Have State? section explains some of the reasons why this might be a good idea.

Comments