简体   繁体   English

为什么 React 状态没有正确更新?

[英]Why is the React state not being updated properly?

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?但是状态没有正确更新,会发生什么?

Setting the state in React acts like an async function.在 React 中设置状态就像一个异步函数。
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.这意味着当您设置状态并在其后放置一个console.log时,它可能会在状态实际完成更新之前运行。

Which is why we have useEffect , a built-in React hook that activates a callback when one of it's dependencies have changed.这就是我们使用useEffect的原因,这是一个内置的 React 钩子,当其中一个依赖项发生更改时,它会激活回调。

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.console.log将仅在状态更改完成并发生渲染后运行。

  • Note: "difficulty" in the example is interchangeable with whatever other state piece you're dealing with.注意:示例中的“难度”可以与您正在处理的任何其他状态部分互换。

Check the documentation for more info.查看文档以获取更多信息。

When you call setDiff , the new value of difficulty will be updated during the next render.当您调用setDiff时,新的difficulty值将在下一次渲染期间更新。 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.由于您是setDifficulty函数中的console.log ,因此在渲染发生之前,对difficulty.rangeB的引用仍然保持更新前的值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM