useThrottleFn

用于处理节流函数的 Hook。

基础用法

import { useThrottleFn } from 'miaoma-rhooks'
import React, { useState } from 'react'

function Demo() {
    const [value, setValue] = useState(0)
    const { run } = useThrottleFn(
        () => {
            setValue(value + 1)
        },
        {
            wait: 500
        }
    )

    return (
        <div>
            <p>当前值: {value}</p>
            <p>快速点击按钮,每 500ms 至多执行一次</p>
            <button onClick={run}>点击 +1</button>
        </div>
    )
}

API

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

Params

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

Options

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

Result

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

进阶用法

仅首次执行

import { useThrottleFn } from 'miaoma-rhooks'
import React, { useState } from 'react'

function LeadingOnlyDemo() {
    const [value, setValue] = useState(0)
    const { run } = useThrottleFn(
        () => {
            setValue(value + 1)
        },
        {
            wait: 500,
            leading: true, // 在延迟开始前执行
            trailing: false // 在延迟结束后不执行
        }
    )

    return (
        <div>
            <p>当前值: {value}</p>
            <p>点击按钮会立即执行,但 500ms 内只会执行一次,且不会在结束时额外执行</p>
            <button onClick={run}>点击 +1</button>
        </div>
    )
}

仅末次执行

import { useThrottleFn } from 'miaoma-rhooks'
import React, { useState } from 'react'

function TrailingOnlyDemo() {
    const [value, setValue] = useState(0)
    const { run } = useThrottleFn(
        () => {
            setValue(value + 1)
        },
        {
            wait: 500,
            leading: false, // 在延迟开始前不执行
            trailing: true // 在延迟结束后执行
        }
    )

    return (
        <div>
            <p>当前值: {value}</p>
            <p>点击按钮不会立即执行,而是等待 500ms 后执行最后一次调用</p>
            <button onClick={run}>点击 +1</button>
        </div>
    )
}

滚动事件处理

import { useThrottleFn } from 'miaoma-rhooks'
import React, { useState, useEffect } from 'react'

function ScrollDemo() {
    const [scrollPosition, setScrollPosition] = useState(0)
    const [scrollCount, setScrollCount] = useState(0)
    const [throttledCount, setThrottledCount] = useState(0)

    // 不使用节流的滚动处理
    useEffect(() => {
        const handleScroll = () => {
            setScrollPosition(window.scrollY)
            setScrollCount(c => c + 1)
        }

        window.addEventListener('scroll', handleScroll)
        return () => {
            window.removeEventListener('scroll', handleScroll)
        }
    }, [])

    // 使用节流的滚动处理
    const { run: handleThrottledScroll } = useThrottleFn(
        () => {
            setThrottledCount(c => c + 1)
        },
        {
            wait: 200
        }
    )

    useEffect(() => {
        window.addEventListener('scroll', handleThrottledScroll)
        return () => {
            window.removeEventListener('scroll', handleThrottledScroll)
        }
    }, [handleThrottledScroll])

    return (
        <div style={{ height: '200vh' }}>
            <div style={{ position: 'fixed', top: 0, left: 0, right: 0, background: '#fff', padding: 16 }}>
                <p>滚动位置: {scrollPosition}px</p>
                <p>滚动事件触发次数: {scrollCount}</p>
                <p>节流后的触发次数: {throttledCount}</p>
                <p>请滚动页面查看效果</p>
            </div>
        </div>
    )
}