useDebounceFn

用于处理防抖函数的 Hook。

基础用法

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

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

    return (
        <div>
            <p>当前值: {value}</p>
            <button onClick={run}>点击 +1</button>
        </div>
    )
}

API

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

Params

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

Options

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

Result

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

进阶用法

立即执行

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

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

    return (
        <div>
            <p>当前值: {value}</p>
            <p>点击按钮会立即执行,但 500ms 内重复点击不会重复触发</p>
            <button onClick={run}>点击 +1</button>
        </div>
    )
}

取消防抖

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

function CancelDemo() {
    const [value, setValue] = useState(0)
    const { run, cancel } = useDebounceFn(
        () => {
            setValue(value + 1)
        },
        {
            wait: 1000
        }
    )

    return (
        <div>
            <p>当前值: {value}</p>
            <button onClick={run}>点击 +1 (延迟 1 秒)</button>
            <button onClick={cancel} style={{ marginLeft: 8 }}>
                取消
            </button>
        </div>
    )
}

搜索框应用

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

function SearchDemo() {
    const [searchTerm, setSearchTerm] = useState('')
    const [results, setResults] = useState([])
    const [loading, setLoading] = useState(false)

    const { run: debouncedSearch } = useDebounceFn(
        async value => {
            if (!value) {
                setResults([])
                return
            }

            setLoading(true)
            try {
                // 模拟 API 请求
                await new Promise(resolve => setTimeout(resolve, 500))
                // 假设这是搜索结果
                setResults(['苹果', '香蕉', '橙子', '葡萄', '西瓜'].filter(item => item.includes(value)))
            } finally {
                setLoading(false)
            }
        },
        {
            wait: 500
        }
    )

    const handleChange = e => {
        const value = e.target.value
        setSearchTerm(value)
        debouncedSearch(value)
    }

    return (
        <div>
            <input value={searchTerm} onChange={handleChange} placeholder="输入水果名称搜索" style={{ width: 200 }} />
            {loading ? (
                <p>加载中...</p>
            ) : (
                <ul>
                    {results.map((item, index) => (
                        <li key={index}>{item}</li>
                    ))}
                </ul>
            )}
        </div>
    )
}