useDebounceEffect
A hook to debounce an effect
Loading...
Installation
npx shadcn@latest add @hooks/use-debounce-effectpnpm dlx shadcn@latest add @hooks/use-debounce-effectyarn dlx shadcn@latest add @hooks/use-debounce-effectbun x shadcn@latest add @hooks/use-debounce-effectCopy and paste the following code into your project.
import { debounce } from 'es-toolkit'
import { useMemo } from 'react'
import { useLatest } from '@/registry/hooks/use-latest'
import { useUnmount } from '@/registry/hooks/use-unmount'
import type { DebounceOptions } from 'es-toolkit'
export type { DebounceOptions }
export function useDebounceFn<Fn extends (...args: any[]) => any>(
fn: Fn,
debounceMs?: number,
options?: DebounceOptions,
) {
const fnRef = useLatest(fn)
const debouncedFn = useMemo(
() =>
debounce(
(...args: Parameters<Fn>) => fnRef.current(...args),
debounceMs ?? 1000,
options,
),
[],
)
useUnmount(() => debouncedFn.cancel())
return {
run: debouncedFn,
cancel: debouncedFn.cancel,
flush: debouncedFn.flush,
}
}import { useEffect, useRef } from 'react'
import { useUnmount } from '@/registry/hooks/use-unmount'
import type { DependencyList, EffectCallback } from 'react'
export function useUpdateEffect(effect: EffectCallback, deps: DependencyList) {
const mounted = useRef(false)
// for react-refresh
useUnmount(() => {
mounted.current = false
})
useEffect(() => {
if (!mounted.current) {
mounted.current = true
return
}
return effect()
}, deps)
}import { useEffect, useState } from 'react'
import { useDebounceFn } from '@/registry/hooks/use-debounce-fn'
import { useUpdateEffect } from '@/registry/hooks/use-update-effect'
import type { DependencyList, EffectCallback } from 'react'
import type { DebounceOptions } from '@/registry/hooks/use-debounce-fn'
export function useDebounceEffect(
effect: EffectCallback,
deps: DependencyList,
debounceMs?: number,
options?: DebounceOptions,
) {
const [flag, setFlag] = useState({})
const { run } = useDebounceFn(
() => {
setFlag({})
},
debounceMs,
options,
)
useEffect(() => {
return run()
}, deps)
useUpdateEffect(() => {
return effect()
}, [flag])
}API
interface DebounceOptions {
/**
* An optional AbortSignal to cancel the debounced function.
*/
signal?: AbortSignal
/**
* An optional array specifying whether the function should be invoked on the leading edge, trailing edge, or both.
* If `edges` includes "leading", the function will be invoked at the start of the delay period.
* If `edges` includes "trailing", the function will be invoked at the end of the delay period.
* If both "leading" and "trailing" are included, the function will be invoked at both the start and end of the delay period.
* @default ["trailing"]
*/
edges?: Array<'leading' | 'trailing'>
}
/**
* A hook to debounce an effect
* @param effect - The effect to debounce
* @param deps - The dependencies to debounce the effect on
* @param debounceMs - The debounce time in milliseconds default to 1000
* @param options - The options for the debounce effect
* @returns The debounced effect
*/
export function useDebounceEffect(
effect: EffectCallback,
deps: DependencyList,
debounceMs?: number,
options?: DebounceOptions,
): voidCredits
Last updated on