Hello,
I'm creating a game where you have to roll ten dice and get their numbers to match. You can reroll the dice and you can click on a die to freeze it (keep it's number/don't reroll)
I'm storing dice data in a useState that holds an array of objects
When I try to update the useState object by directly reversing the die's isFrozen boolean, it doesn't work. Instead, it works when I make a copy of the die object, update it, and return it
I don't understand why I can't directly update the die object in the array. Why do I have to create a copy of the die object?
useState
const [dice, setDice] = useState(() => {
const diceArray = [];
for (let i = 1; i <= 10; i++) {
diceArray.push({ id: nanoid(), num: rollDice(), isFrozen: false });
}
return diceArray;
});
freezeDie code - Doesn't work
const freezeDie = (id) => {
setDice((oldDice) =>
oldDice.map((die) => {
if (die.id === id) {
console.log("die", die);
console.log("");
die.isFrozen = !die.isFrozen; // THIS LINE
}
return die;
})
);
};
Result
- the first click reverses the isFrozen boolean (it freezes the die - intended)
- future clicks reverses the isFrozen boolean twice (basically nothing changes - not intended)
freezeDie code - Works
const freezeDie = (id) => {
setDice((oldDice) =>
oldDice.map((die) => {
if (die.id === id) {
console.log("die", die);
console.log("");
return { ...die, isFrozen: !die.isFrozen }; // THIS LINE
}
return die;
})
);
};
Result
- the first click reverses the isFrozen boolean (it freezes the die - intended)
- future clicks also reverse the isFrozen boolean but call the function twice (not sure why it's being called twice)
Top comments (0)