如何实现定时器的功能_子程序调用编程实例

(3) 2024-09-10 19:23

Hi,大家好,我是编程小6,很荣幸遇见你,我把这些年在开发过程中遇到的问题或想法写出来,今天说一说
如何实现定时器的功能_子程序调用编程实例,希望能够帮助你!!!。

若在定时器内直接使用 React 的代码,可能会收到意想不到的结果。如我们想实现一个每 1 秒加 1 的定时器:

const App = () => { const [count, setCount] = useState(0); useEffect(() => { const timer = setInterval(() => { setCount(count + 1); }, 1000); return () => clearInterval(timer); }, []); return <div className="App">{count}</div>; };

可以看到,coun 从 0 变成 1 以后,就再也不变了。为什么会这样?

如何实现定时器的功能_子程序调用编程实例_https://bianchenghao6.com/blog__第1张

尽管由于定时器的存在,组件始终会一直重新渲染,但定时器的回调函数是挂载期间定义的,所以它的闭包永远是对挂载时 Counter 作用域的引用,故 count 永远不会超过 1。

针对这个单一的 hook 调用,还比较好解决,例如可以监听 count 的变化,或者通过 useState 的 callback 传参方式。

const App = () => {
  const [count, setCount] = useState(0);

  // 监听 count 的变化,不过这里将定时器改成了 setTimeout
  // 即使不修改,setInterval()的timer也会在每次渲染时被清除掉,
  // 然后重新启动一个新的定时器
  useEffect(() => {
    const timer = setTimeout(() => {
      setCount(count + 1);
    }, 1000);
    return () => clearInterval(timer);
  }, [count]);

  // 以回调的方式
  // 回调的方式,会计算回调的结果,然后作为下次更新的初始值
  // 详情可见: https://www.xiabingbao.com/post/react/react-usestate-rn5bc0.html#5.+updateReducer
  useEffect(() => {
    const timer = setInterval(() => {
      setCount(count => count + 1);
    }, 1000);
    return () => clearInterval(timer);
  }, []);

  return <div className="App">{count}</div>;
};

当然还有别的方式也可以实现 count 的更新。那要是调用更多的 hook,或者更复杂的代码,该怎么办呢?这里我们可以封装一个新的 hook 来使用:

COPYJAVASCRIPT// https://overreacted.io/zh-hans/making-setinterval-declarative-with-react-hooks/ const useInterval = (callback: () => void, delay: number | null): void => { const savedCallback = useRef(callback); useEffect(() => { savedCallback.current = callback; }); useEffect(() => { function tick() { savedCallback.current(); } if (delay !== null) { const id = setInterval(tick, delay); return () => clearInterval(id); } }, [delay]); };

今天的分享到此就结束了,感谢您的阅读,如果确实帮到您,您可以动动手指转发给其他人。

上一篇

已是最后文章

下一篇

已是最新文章

发表回复