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)