I have a div with 10 elements, which are to be updated one-by-one with a time delay of say 2secs. Below is the code for the same
for(let boxNo=0; boxNo<10; bo
You're breaking two of the fundamental rules of React:
Don't mutate state directly
for(let boxNo=0; boxNo<10; boxNo++){
setTimeout(() => {
nodes[boxNo].isMarked = true; // <==== here
this.setState({nodes});
}, (boxNo*200)+boxNo);
);
}
If updating state based on existing state, use the callback form because state updates may be asynchronous (and in any case, in your example, time has passed):
for(let boxNo=0; boxNo<10; boxNo++){
setTimeout(() => {
nodes[boxNo].isMarked = true;
this.setState({nodes}); // <==== here
}, (boxNo*200)+boxNo);
);
}
Instead, see ***
comments and associated code:
// **IF** `nodes` is an array
for(let boxNo=0; boxNo<10; boxNo++){
setTimeout(() => {
// *** Note using callback form (#2)
this.setState(({nodes} => {
// *** *Copy* the parts of state you're going to modify (#1)
nodes = [...nodes];
nodes[boxNo] = {...nodes[boxNo], isMarked: true};
return {nodes};
});
}, (boxNo*200)+boxNo);
);
}
that setState
call can also be written like this at the (trivial) expense of creating a temporary object:
this.setState(({nodes} => ({
nodes: Object.assign([], nodes, {[boxNo]: {...nodes[boxNo], isMarked: true}})
});
or
// **IF** `nodes` is a non-array object
for(let boxNo=0; boxNo<10; boxNo++){
setTimeout(() => {
// *** Note using callback form (#2)
this.setState(({nodes} => {
// *** *Copy* the parts of state you're going to modify (#1)
return {
nodes: {
...nodes,
[boxNo]: {...nodes[boxNo], isMarked: true}
}
};
});
}, (boxNo*200)+boxNo);
);
}