React项目实践中产出的hooks

268 阅读1分钟

我正在参加「掘金·启航计划」

收集工作实践中好用的React hook,持续收集中。。。

1.useInterval 定时器hook

场景:需要一个可以停止和重起的定时器hook

用法:给hook传入一个函数,hook可以定时调用此函数。可以传入延时时间、是否立即执行,hook最终返回清空定时器函数和重起定时器函数。

/*
    定期执行,默认5秒
    fn 执行函数 使用usecallback包裹
    delay 间隔时间
    options  immediate立即执行
    @return cleareIntervalHandler 定时清除函数  resstartIntervalHandler 重起定时器
*/
import { useEffect, useRef } from 'react'

function useInterval(
    fn: () => void,
    delay: number = 5000,
    options: {
        immediate: boolean;
    } = { immediate: true },
): [clearIntervalHandler: () => void, restartIntervalHandler: () => void] {
    const immediate = options?.immediate
    const timerRef = useRef<number>()

    const clearIntervalHandler = () => {
        if (timerRef.current) {
            clearInterval(timerRef.current)
        }
    }
    const restartIntervalHandler = () => {
        clearIntervalHandler()
        timerRef.current = window.setInterval(() => {
            fn()
        }, delay)
    }
    useEffect(() => {
        if (typeof delay !== 'number' || delay < 0) return;
        if (immediate) {
            fn()
        }
         timerRef.current = window.setInterval(() => {
             fn()
         }, delay)
        return () => {
            clearInterval(timerRef.current)
        }
    }, [delay, fn])

    return [clearIntervalHandler, restartIntervalHandler]
}

export {
    useInterval
}

2.useDownloadFile 下载文件hook 用法:向hook返回一个下载文件函数,此函数需要传入下载地址、参数、文件名

import axios from 'axios'
import qs from 'qs'

export function useDownloadFile() {
    const downloadHandle = (downloadUrl: string, params: object, fileName: string) => {
        axios({
            method: 'post',
            url: downloadUrl,
            headers: { "Content-Type": 'application/x-www-form-urlencoded' },
            data: qs.stringify(params),
            responseType: 'blob'
        }).then(res => {
            const blob = res.data
            if ('msSaveOrOpenBlob' in navigator) {
                const blobStr = new Blob([res.data]);
                (window as any).navigator.msSaveOrOpenBlob(blobStr, fileName)
                return
            }
            const url = window.URL.createObjectURL(blob)
            const a = document.createElement('a')
            a.href = url
            a.download = fileName
            document.body.appendChild(a)
            a.click()
            document.body.removeChild(a)
            window.URL.revokeObjectURL(url)
        })
    }

    return downloadHandle
}

3.useFnDebounce 防抖hook-函数防抖 用法:传入函数、依赖、防抖延迟时间

import { useEffect, useState } from 'react'

export const useFnDebounce = <T>(fn: Function, dep: T, delay = 60) => {
  useEffect(() => {
    const timer = setTimeout(() => fn(), delay)
    return () => clearTimeout(timer)
  }, [fn, dep, delay])
}

3.useParamDebounce 防抖hook-变量防抖 用法:传入变量、延迟时间

import { useEffect, useState } from 'react'

export const useParamDebounce = <T>(value:T, delay = 60): T => {
  const [val, setVal] = useState<T>(value)

  useEffect(() => {
    const timer = setTimeout(() => {
      setVal(value)
    }, delay)
    return () => clearTimeout(timer)
  }, [value, delay])

  return val
}

平常工作中会遇到一些可以封装后重复使用hook的场景,将这些hook收集起来提供方便