In my code below, I placed setCards inside a setTimeout but after 1 second the render will only be correct if I pass in a copy of the state: [...cardStates] rather than cardStates itself. If I don't do this, the setCards will render the cardStates as it was before hideCards() made changes to the state.
I think this has something to do with the state when setTimeout places the function in the queue but I don't fully grasp what's happening. I've dug around a lot and things like stale closures came up but I'm not sure if this is the correct direction. Can someone help clear this up for me? Thank you.
useEffect(() => {
if (numberShowing(cardStates) === 2) {
setTimeout(() => {
setCards(hideCards([...cardStates]));
}, 1000)
}
})
function hideCards(cards) {
let showing = cards.filter(card => {
return card.cardState === 'showing';
})
showing.forEach(card => {
card.cardState = 'hiding';
});
return cards;
}
Because a state is immutable, you can't manipulate it directly. Try to debug something with mutable data, in some case it can become painful.
That's not the only benefit to immutability but i won't do better explanation than you can already find on internet ;).