ahooks源码分析-useThrottleFn

794 阅读2分钟

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

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

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

今天分享 第21个 hooks-useThrottleFn

useThrottleFn

useThrottleFn 的作用是什么

useThrottleFn 的作用是 用来处理函数节流的 Hook。

接下来 看下 API

API

const {
  run,
  cancel,
  flush
} = useThrottleFn(
  fn: (...args: any[]) => any,
  options?: Options
);

Params

一共有2个参数

第1个参数是fn,表示需要节流执行的函数

第2个参数是options,表示配置节流的行为

参数说明类型默认值
fn需要节流的函数(...args: any[]) => any-
options配置节流的行为Options-

Options

一共有3个配置项

第1个参数是wait,表示等待时间,单位为毫秒

第2个参数是leading,表示是否在延迟开始前调用函数

第3个参数是trailing,表示是否在延迟开始后调用函数

参数说明类型默认值
wait等待时间,单位为毫秒number1000
leading是否在延迟开始前调用函数booleantrue
trailing是否在延迟开始后调用函数booleantrue

Result

返回的结果有3个

第1个是run,表示触发执行 fn,函数参数将会传递给 fn

第2个是cancel,表示取消当前防抖

第3个是flush,表示立即调用当前节流函数

|| 参数 | 说明 | 类型 | | ------ | ---------------------------------- | ------------------------- | | run | 触发执行 fn,函数参数将会传递给 fn | (...args: any[]) => any | | cancel | 取消当前节流 | () => void | | flush | 当前节流立即调用 | () => void |

接下来 看下 用法

基础用法

频繁调用 run,但只会在所有点击完成 500ms 后执行一次相关函数

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

export default () => {
  const [value, setValue] = useState(0);
  const { run } = useDebounceFn(
    () => {
      setValue(value + 1);
    },
    {
      wait: 500,
    },
  );

  return (
    <div>
      <p style={{ marginTop: 16 }}> Clicked count: {value} </p>
      <button type="button" onClick={run}>
        Click fast!
      </button>
    </div>
  );
};

当快速点击按钮的时候,只增加1

image.png

接下来一起看下 源码

源码

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

export interface DebounceOptions {
  wait?: number;
  leading?: boolean;
  trailing?: boolean;
}


fn: T, options?: DebounceOptions

2.使用useLatest这个hooks,将传入的fn包裹住,返回最新的fnRef

const fnRef = useLatest(fn);

3.获取传入的等待时间

const wait = options?.wait ?? 1000;

4.然后编写防抖函数,这里引入throttle第三方库,

import throttle from 'lodash/throttle';

const throttled = useMemo(
    () =>
      throttle(
        (...args: Parameters<T>): ReturnType<T> => {
          return fnRef.current(...args);
        },
        wait,
        options,
      ),
    [],
  );

5.在卸载的时候销毁

useUnmount(() => {
    throttled.cancel();
  });

6.最后返回这几个方法

return {
    run: throttled,
    cancel: throttled.cancel,
    flush: throttled.flush,
  };

其他hooks

useLatest

useEventListener

useClickAway

useDocumentVisibility

useTitle