当前位置: 首页 > 面试题库 >

在setInterval中使用React状态挂钩时状态未更新

冀啸
2023-03-14
问题内容

我正在尝试新的React Hooks,并有一个带有计数器的Clock组件,该计数器应该每秒增加一次。但是,该值不会增加到超过一。

function Clock() {

  const [time, setTime] = React.useState(0);

  React.useEffect(() => {

    const timer = window.setInterval(() => {

      setTime(time + 1);

    }, 1000);

    return () => {

      window.clearInterval(timer);

    };

  }, []);



  return (

    <div>Seconds: {time}</div>

  );

}



ReactDOM.render(<Clock />, document.querySelector('#app'));


<script src="https://unpkg.com/react@16.7.0-alpha.0/umd/react.development.js"></script>

<script src="https://unpkg.com/react-dom@16.7.0-alpha.0/umd/react-dom.development.js"></script>



<div id="app"></div>

问题答案:

原因是传递给setInterval的闭包中的回调仅访问time第一个渲染器中的变量,而无法访问time后续渲染器中的新值,因为useEffect()第二次未调用。

time``setInterval回调中的值始终为0 。

就像setState您熟悉的状态挂钩一样,状态挂钩有两种形式:一种是处于更新状态的状态,另一种是将当前状态传入的回调形式。您应该使用第二种形式,并读取setState回调中的最新状态值以在递增之前,请确保您具有最新的状态值。

奖励:替代方法

Dan Abramov setInterval在他的博客文章中深入探讨了有关使用钩子的主题,并提供了解决此问题的替代方法。强烈建议阅读!

function Clock() {

  const [time, setTime] = React.useState(0);

  React.useEffect(() => {

    const timer = window.setInterval(() => {

      setTime(prevTime => prevTime + 1); // <-- Change this line!

    }, 1000);

    return () => {

      window.clearInterval(timer);

    };

  }, []);



  return (

    <div>Seconds: {time}</div>

  );

}



ReactDOM.render(<Clock />, document.querySelector('#app'));


<script src="https://unpkg.com/react@16.7.0-alpha.0/umd/react.development.js"></script>

<script src="https://unpkg.com/react-dom@16.7.0-alpha.0/umd/react-dom.development.js"></script>



<div id="app"></div>


 类似资料:
  • 我正在试用新的反应挂钩,并有一个时钟组件,计数器应该每秒钟增加一次。但是,该值不增加超过1。

  • 我正在尝试使用状态将一个表单输入值复制到另一个表单输入值,但状态没有更新 我创建了一个带有按钮的表单,其中左侧表单输入的值应复制到右侧表单输入。这是我的代码: 无论我做什么,dbSecName的状态都不会改变。我试着设置一个新的常量。我尝试使onclick函数异步并等待。如果我为我试图设置的变量的值添加,我可以正确地看到它,但是dbSecName的console.log总是显示原始值。 我真的不知

  • 我正在尝试新的hooks功能,并坚持认为我的状态没有更新。 实际上,状态已更新(我可以在console.log中看到更新的值,并且我的组件会重新运行useEffect),但是useEffect方法使用我的旧状态,并仅将签名保存给第一个用户,而活动用户在状态中确实发生了更改。 我想过添加useCallback,并将我的方法移动到use效果或组件本身,但我可以设法让它工作。 状态: 这是我的效果: 这

  • 我有一个小的井字游戏,一切都很好,除了我正在努力寻找在代码中放置完成功能的位置。让我给你看; 这基本上是整个游戏,我在另一个文件中有一个整理函数,就像这样; 完成功能也可以正常工作,但是由于useState是异步工作的,我知道这一点,我正在努力把它放在哪里。如果我把点击功能放在里面,它就不能对新的状态做出反应,只能对之前的状态做出反应。如果我把外面加上只是if语句,它会说渲染太多,因为我正在设置获

  • 我有一个函数反应组件,它有一个从10000开始到0的计数器。 我正在组件安装期间使用useEffect挂钩设置setInterval回调。然后,回调更新计数器状态。 但是不知道为什么,值从来没有减少过。每次回调运行为10000。 (我正在使用react 功能组件如下所示: 这里是codesandbox的链接:链接

  • 我正在React中使用useState钩子,状态将不会在