I have the following code :-
const [dice, setDice] = React.useState(allNewDice()) // Array of objects with the following properties: `value` (random digit between 1 and 6), `id` (unique id), `isHeld` (boolean)
function holdDice(id) {
const heldDie = dice.findIndex(die => die.id === id)
setDice(prevDice => {
prevDice[heldDie].isHeld = !prevDice[heldDie].isHeld
return prevDice
})
}
The function holdDice is working as expected. It updates prevDice's first element's isHeld property to the opposite of what was previously, as evident from logging it to the console. But the only problem is, the state is not getting updated.
So I tried making a copy of prevDice and then returning the copy (using the spread (...) operator) :-
const [dice, setDice] = React.useState(allNewDice()) // Array of objects with the following properties: `value` (random digit between 1 and 6), `id` (unique id), `isHeld` (boolean)
function holdDice(id) {
const heldDie = dice.findIndex(die => die.id === id)
setDice(prevDice => {
prevDice[heldDie].isHeld = !prevDice[heldDie].isHeld
return [...prevDice]
})
}
And this works perfectly.
Can anyone please explain why this behaviour? Why can't I return the previous state passed in to be set as the new state, even when I am not returning the previous state, exactly as it was?
I understand that it's expensive to re-render the component and that maybe React does not update the state when the previous and the new states are equal. But here, the previous and the new states are not equal.
My first guess was that it might have been related to React not deep checking whether the objets of the array prevDice have been changed or not, or something like that. So I created an array of Numbers and tried changing it's first element to some other number, but unless i returned a copy of the array, the state still did not change.
Any help would be greatly appreciated. Thank you!