如何在 React 中的功能组件上使用 setInterval 更新状态

Kel*_*sta 3 timer setinterval reactjs react-hooks

我正在尝试实现倒计时,但状态没有按预期更新。它停留在初始值 30。我不知道如何解决它。有人可以帮我吗?

  const [timer, setTimer] = useState(30);

  function handleTimer() {
    const interval = setInterval(() => {
      setTimer((count) => count - 1);
      if (timer <= 0) {
        clearInterval(interval);
      }
    }, 1000);
  }

  useEffect(() => {
    handleTimer();
  }, []);
Run Code Online (Sandbox Code Playgroud)

Ahm*_*rek 8

问题是关于 javascript 闭包,你可以在这里阅读更多相关信息

此外,丹有一篇完整详细的文章讨论了这个具体问题。我强烈建议你阅读它。

这是针对您的问题的快速解决方案和演示。首先,useEffect每次重新挂载组件时都会执行。根据您的代码,这可能会发生在许多不同的场景中。因此,TheuseEffect每次都会以新的数据开始并结束。

所以我们需要的就是将我们的值保存到 ref 中,这样我们就可以在每次重新渲染时使用相同的引用。

// Global Varibales
const INITIAL_TIMER = 30;
const TARGET_TIMER = 0;
Run Code Online (Sandbox Code Playgroud)
// Code refactoring
  const [timer, setTimer] = useState(INITIAL_TIMER);
  const interval = useRef();

  useEffect(() => {
    function handleTimer() {
      interval.current = setInterval(() => {
        setTimer((count) => count - 1);
      }, 1000);
    }

    if (timer <= TARGET_TIMER && interval.current) {
      clearInterval(interval.current);
    }
    if (timer === INITIAL_TIMER) {
      handleTimer();
    }
  }, [timer]);
Run Code Online (Sandbox Code Playgroud)