I'm making a math game, and I'd like the range of the operands to be updated after a certain amount of questions. I have this code to set the difficulty
const [difficulty, setDiff] = useState({rangeA:[1, 10], rangeB:[1, 10]});
function setDifficulty(op) {
let rangeA = [];
let rangeB = [];
if (question < 5) { //question state is incremented everytime the answer is correct, which triggers the next question
rangeA = [0, 100];
rangeB = [0, 10];
}
else if (question < 8) {
rangeA = [0, 100];
rangeB = [0, 100];
}
setDiff({...difficulty, rangeA, rangeB});
console.log(rangeB, difficulty.rangeB); // when question is 5, this logs [0, 100] [0, 10], but they should be the same value [0,100]
}
but the state doesn't update properly, what could be happening?
CodePudding user response:
Setting the state in React acts like an async function.
Meaning that the when you set the state and put a console.log
right after it, it will likely run before the state has actually finished updating.
Which is why we have useEffect
, a built-in React hook that activates a callback when one of it's dependencies have changed.
Example:
useEffect(() => {
console.log(difficulty)
// Whatever else we want to do after the state has been updated.
}, [difficulty])
This console.log
will run only after the state has finished changing and a render has occurred.
- Note: "difficulty" in the example is interchangeable with whatever other state piece you're dealing with.
Check the documentation for more info.
CodePudding user response:
When you call setDiff
, the new value of difficulty
will be updated during the next render.
Since you are console.log
ging inside the setDifficulty
function, before the render occurred, the reference to difficulty.rangeB
still holds the value before the update.