SetInterval 未显示更新状态 [英] SetInterval is not showing updated state

查看:50
本文介绍了SetInterval 未显示更新状态的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在调用 setInterval 函数之前,我已将状态设置为 true.但是即使 useEffect 钩子是用状态的新值触发的,它也没有反映在 setInterval 函数中.

代码沙箱在这里:https://jsfiddle.net/6e05tc2L/3/

let 间隔;const 组件 = () =>{React.useEffect(() => {console.log('状态更新为', state);});const [state, setState] = React.useState(false);const on = () =>{设置状态(真);间隔 = setInterval(() => {控制台日志(状态);}, 1000);}const off = () =>{设置状态(假);清除间隔(间隔);}const 切换 = () =>状态 ?关():开()返回 (<div><button onClick={toggle}>切换状态</button>

);}ReactDOM.render(<组件/>,document.getElementById('容器'));

它不应该在更新后使用更新的 state 值吗?

解决方案

传递给 useEffect 的函数内的值在每次渲染时都会刷新,因为 useEffect 使用传递给它的函数的新定义.

但是传递给 setInterval 的函数只定义了一次,它会关闭 state 的旧值.哪个还没有更新.

使用钩子进行闭包很棘手,但需要注意的是 useEffect 会为每次渲染创建一个新函数,因此每次函数关闭新状态值时都会创建一个新函数.

诀窍是在 useEffect 本身内部调用与 setInterval 相关的代码,这本身取决于状态的变化值

React.useEffect(() => {如果(状态){间隔 = setInterval(() => {控制台日志(状态);}, 1000);} 别的 {清除间隔(间隔);}}, [状态]);

或者,更好的是使用 useInterval 钩子来为您处理这些细节.

I have set the state to true before calling the setInterval function. But even though the useEffect hook is being triggered with the new value of the state, it's not being reflected in the setInterval function.

Code sandbox here: https://jsfiddle.net/6e05tc2L/3/

let interval;
const Component = () => {
  React.useEffect(() => {
    console.log('State updated to', state);
  });
  const [state, setState] = React.useState(false);
  const on = () => {
    setState(true);
    interval = setInterval(() => {
      console.log(state);
    }, 1000);
    }
  const off = () => {
    setState(false);
    clearInterval(interval);
  }
  const toggle = () => state ? off() : on()

  return (<div>
    <button onClick={toggle}>Toggle State</button>
   </div>);
}

ReactDOM.render(
  <Component />,
  document.getElementById('container')
);

Shouldn't it be using the newer value of state once it's updated?

解决方案

The values inside the function which you pass to useEffect are refreshed on every render, because useEffect uses a new definition of the function you pass to it.

But the function passed to setInterval is defined once and it closes over the old stale value of state. Which has not yet updated.

Closures are tricky with hooks, but the thing to realize is that useEffect creates a new function for each render and hence each time the function closes over a fresh state value.

The trick then is to call your setInterval related code inside a useEffect itself, which itself depends on the changing value of state

React.useEffect(() => {
  if(state) {

    interval = setInterval(() => {
      console.log(state);
    }, 1000);
  } else {
    clearInterval(interval);
  }

}, [state]);

Or, better, use a useInterval hook which takes care of these details for you.

这篇关于SetInterval 未显示更新状态的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆