How to Properly Set Multiple States Inside Multiple useEffect Hooks in React
Suppose we have a state that we’ve initialized using useState()
.
const [ count, setCount ] = useState({
a: 0,
b: 0
});
Suppose we want to update multiple attributes inside count
using different useEffect()
hooks.
We might think to write it this way.
useEffect(() => {
setCount({ ...count, a: props.a });
}, [props.a]);
useEffect(() => {
setCount({ ...count, b: props.b });
}, [props.b]);
The problem with this approach is that a
may never be updated.
Both useEffect()
hooks run in the same React cycle and the same context. This means that the value of a
and b
inside ...count
is exactly the same in both useEffect()
hooks. The second setCount()
will inevitably replace the first setCount()
.
In order to solve this problem, we can do this instead:
useEffect(() => {
setCount((count) => ({ ...count, a: props.a }));
}, [props.a]);
useEffect(() => {
setCount((count) => ({ ...count, b: props.b }));
}, [props.b]);
After each setCount()
, we will receive the most updated value of count
.