为什么一个简单的``usefeft''在扭曲“ setInterval/timeout”时不会采用更新值。里面

发布于 2025-02-10 03:33:02 字数 1106 浏览 1 评论 0原文

为什么一个简单的使用在内部扭曲任何setInterval/timeout时不会采用更新值;

code sandbox

where variable stopped to initial value;

import { useState, useEffect } from "react";
let timerRef;
const StopWatch = () => {
  const [time, setTime] = useState(0);
  const [isPause, setPause] = useState(false);
  useEffect(() => {
    timerRef = setInterval(() => {
      console.log({ time });
      if (!isPause) {
        setTime(time + 1);
      }
    }, 5000);
    return () => clearInterval(timerRef);
  }, []);
  const startWatch = () => {
    setPause(false);
  };
  const stopWatch = () => {
    setPause(true);
  };
  return (
    <>
      time: {time}
      <button onClick={startWatch}>Start</button>
      <button onClick={stopWatch}>stop</button>
    </>
  );
};
export { StopWatch };

Why a simple useEffect is not taking updated value when it is warping any setInterval/timeout inside;

Code sandbox

where variable stopped to initial value;

import { useState, useEffect } from "react";
let timerRef;
const StopWatch = () => {
  const [time, setTime] = useState(0);
  const [isPause, setPause] = useState(false);
  useEffect(() => {
    timerRef = setInterval(() => {
      console.log({ time });
      if (!isPause) {
        setTime(time + 1);
      }
    }, 5000);
    return () => clearInterval(timerRef);
  }, []);
  const startWatch = () => {
    setPause(false);
  };
  const stopWatch = () => {
    setPause(true);
  };
  return (
    <>
      time: {time}
      <button onClick={startWatch}>Start</button>
      <button onClick={stopWatch}>stop</button>
    </>
  );
};
export { StopWatch };

output

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

溇涏 2025-02-17 03:33:02

通过时间的依赖,这应该有效

useEffect(() => {
    let _time = time;
    console.log({ time });
    timerRef = setInterval(() => {
      console.log({ _time });
      if (!isPause) {
        setTime(_time + 1);
      }
    }, 5000);
    return () => clearInterval(timerRef);
  }, [time]);

pass dependency of time and this should work

useEffect(() => {
    let _time = time;
    console.log({ time });
    timerRef = setInterval(() => {
      console.log({ _time });
      if (!isPause) {
        setTime(_time + 1);
      }
    }, 5000);
    return () => clearInterval(timerRef);
  }, [time]);
唔猫 2025-02-17 03:33:02

这是因为您正在访问time从关闭中访问值,并且由于您仅定义Settimeout处理程序一次(初始化),因此它将始终参考该初始值的time time> 。我建议,对于此用例,仅将状态更新器与回调一起使用,并且它将为您提供机制,以轻松地使用Previos One更新状态,并且无法直接访问状态。只需重写settime(_time + 1) to settime(previme =&gt; previme + 1)

That is because you are accessing time value from the closure, and since you are defining setTimeout handler only once (on initialization) then it will always refer to that initial value for time. I suggest, for this use case, just to use state updater with callback, and like that it will provide you mechanism to easily update state with previos one, and by not accessing state directly. Just rewrite setTime(_time + 1) to setTime(prevTime => prevTime + 1)

十六岁半 2025-02-17 03:33:02

CODESANDBOX已经警告过您。

CodeSandbox already warned you about that.

enter image description here

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文