I have a component similar to the below with a number of functional setState
calls to change an array of objects. I'm using functional setState to make things easier for testing.
In this scenario, with completeDef
, I'm calling completeCurrentDef
that will empty the defs
array, which is used in rendering. Then I call useNextDefsIfEmpty
to replace defs
with nextDefs
.
Right now, this works, but I'm concerned about it rendering in between the two setState
calls, which if it does, currentDef
will be undefined
and break my application. Yes, I could add a default or something to ensure this doesn't happen, but I only want to do that if necessary.
How does React's lifecycle work in this case?
Will React render in between the two functional setState
calls or will it process all setState
calls and then render? Or does something else happen?
class DefinitionList extends React.Component {
state = {
defs: [{word: 'some', meaning: 'a few'}],
nextDefs: [{word: 'all', meaning: 'everything'}],
completedDefs: [],
};
completeDef = () => {
this.setState(completeCurrentDef);
// can render happen here?
this.setState(useNextDefsIfEmpty);
}
render() {
const {defs} = this.state;
const currentDef = defs[0];
const {word, meaning} = currentDef;
return (
<div onClick={this.completeDef}>
<p>{word}</p>
<p>{meaning}</p>
<p>Learn</p>
</div>
);
}
}
const useNextDefsIfEmpty = state => ({
defs: state.defs.length ? state.defs : state.nextDefs
});
const completeCurrentDef = state => ({
defs: state.defs.slice(1),
completedDefs: state.completedDefs.concat(state.defs[0]),
});
Note: This is not the same as a regular setState
call with an object. This is passing a function into setState
. For more on functional setState
, see this article