欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

通过 React Hooks 声明式地使用 setInterval

程序员文章站 2022-07-05 16:07:16
本文由云+社区发表 作者:Dan Abramov 接触 "React Hooks" 一定时间的你,也许会碰到一个神奇的问题: "用起来没你想的简单" 。 Ryan Florence 在 "他的推文" 里面说到: 不少朋友跟我提起,setInterval 和 hooks 一起用的时候,有种蛋蛋的忧伤。 ......

本文由云+社区发表

作者:dan abramov

接触 react hooks 一定时间的你,也许会碰到一个神奇的问题: setinterval

ryan florence 在里面说到:

不少朋友跟我提起,setinterval 和 hooks 一起用的时候,有种蛋蛋的忧伤。

老实说,这些朋友也不是胡扯。刚开始接触 hooks 的时候,确实还挺让人疑惑的。

但我认为谈不上 hooks 的毛病,而是 react 编程模型setinterval 之间的一种模式差异。相比类(class),hooks 更贴近 react 编程模型,使得这种差异更加突出。

虽然有点绕,但是让两者和谐相处的方法,还是有的。

本文就来探索一下,如何让 setinterval 和 hooks 和谐地玩耍,为什么是这种方式,以及这种方式给你带来了什么新能力


声明:本文采用循序渐进的示例来解释问题。所以有一些示例虽然看起来可以有捷径可走,但是我们还是一步步来。

如果你是 hooks 新手,不太明白我在纠结啥,不妨读一下 react hooks 的和。本文假设读者已经使用 hooks 超过一个小时。


代码呢?

通过下面的方式,我们可以轻松地实现一个每秒自增的计数器:

import react, { usestate, useeffect, useref } from 'react';

function counter() {
  let [count, setcount] = usestate(0);

  useinterval(() => {
    // your custom logic here
    setcount(count + 1);
  }, 1000);

  return <h1>{count}</h1>;
}

codesandbox 线上示例

上述 useinterval 并不是内置的 react hook,而是我实现的一个自定义 hook

import react, { usestate, useeffect, useref } from 'react';

function useinterval(callback, delay) {
  const savedcallback = useref();

  // remember the latest callback.
  useeffect(() => {
    savedcallback.current = callback;
  });

  // set up the interval.
  useeffect(() => {
    function tick() {
      savedcallback.current();
    }
    if (delay !== null) {
      let id = setinterval(tick, delay);
      return () => clearinterval(id);
    }
  }, [delay]);
}

(如果你在错过了,这里也有一个一样的 codesandbox 线上示例

我实现的 useinterval hook 设置了一个计时器,并且在组件 unmount 的时候清理掉了。 这是通过组件生命周期上绑定 setintervalclearinterval 的组合完成的。

这是一份可以在项目中随意复制粘贴的实现,你甚至可以发布到 npm 上。

不关心为什么这样实现的读者,就不用继续阅读了。下面的内容是为希望深入理解 react hooks 的读者而准备的。


哈?!