ahooks源码分析-useTimeout

159 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第30天,点击查看活动详情

今天开始一起学习分享 ahooks 的源码

ahooks是阿里巴巴出品的一套高质量可靠的 React Hooks 库

今天分享 第25个 hooks-useTimeout

useTimeout

useTimeout 的作用是什么

useTimeout 的作用是 一个可以处理 setTimeout 计时器函数的 Hook。

接下来 看下 API

API

useTimeout(
  fn: () => void,
  delay?: number | null
): fn: () => void;

Params

一共有3个参数

第1个参数是fn,表示要定时调用的函数

第2个是delay,表示间隔时间,当设置值为 undefined 时会停止计时器

参数说明类型
fn待执行函数() => void
delay定时时间(单位为毫秒),支持动态变化,,当取值为 undefined 时会停止计时器number | undefined

Result

参数说明类型
clearTimeout清除定时器() => void

接下来 看下 用法

基础用法

每1000ms,执行一次

import React, { useState } from 'react';
import { useTimeout } from 'ahooks';

export default () => {
  const [state, setState] = useState(1);
  useTimeout(() => {
    setState(state + 1);
  }, 3000);

  return <div>{state}</div>;
};

3000ms 后执行一次

image.png

进阶使用

动态修改 delay 以实现定时器间隔变化与暂停。

import React, { useState } from 'react';
import { useTimeout } from 'ahooks';

export default () => {
  const [count, setCount] = useState(0);
  const [delay, setDelay] = useState<number | undefined>(1000);

  const clear = useTimeout(() => {
    setCount(count + 1);
  }, delay);

  return (
    <div>
      <p> count: {count} </p>
      <p style={{ marginTop: 16 }}> Delay: {delay} </p>
      <button onClick={() => setDelay((t) => (!!t ? t + 1000 : 1000))} style={{ marginRight: 8 }}>
        Delay + 1000
      </button>
      <button
        style={{ marginRight: 8 }}
        onClick={() => {
          setDelay(1000);
        }}
      >
        reset Delay
      </button>
      <button onClick={clear}>clear</button>
    </div>
  );
};

image.png

接下来一起看下 源码

源码

1.首先定义传入参数的类型

fn: () => void, delay: number | undefined

2.使用useRef定义一个定时器

const timerRef = useRef<NodeJS.Timer | null>(null);

3.返回清除定时器的函数,在useCallback中判断是否存在定时器,如果存在定时器,则使用clearInterval清除定时器

const clear = useCallback(() => {
    if (timerRef.current) {
      clearTimeout(timerRef.current);
    }
  }, []);

4.使用useLatest包裹传入的函数。判断delay是否存在和小于零,是的话则直接return.如果immediate为true,则直接执行函数。否则的话,在指定时间执行该函数,并清除定时器

 useEffect(() => {
    if (!isNumber(delay) || delay < 0) {
      return;
    }
    timerRef.current = setTimeout(() => {
      fnRef.current();
    }, delay);
    return () => {
      if (timerRef.current) {
        clearTimeout(timerRef.current);
      }
    };
  }, [delay]);

其他hooks

useLatest

useEventListener

useClickAway

useDocumentVisibility

useTitle