防抖 atom

防抖也是在处理网页操作中非常常用的一类操作,尤其是在处理用户的连续输入时非常常用。防抖的处理模式比较单一,可复用性很强,所以可以将其集成到 atom 中进行自动处理。

以下是支持防抖功能的 atom 创建函数的实现。

export default function atomWithDebounce<T>( initialValue: T, delayMilliseconds = 500, shouldDebounceOnReset = false ) { const prevTimeoutAtom = atom<ReturnType<typeof setTimeout> | undefined>( undefined ); const _currentValueAtom = atom(initialValue); const isDebouncingAtom = atom(false); const debouncedValueAtom = atom( initialValue, (get, set, update: SetStateAction<T>) => { clearTimeout(get(prevTimeoutAtom)); const prevValue = get(_currentValueAtom); const nextValue = typeof update === "function" ? (update as (prev: T) => T)(prevValue) : update; const onDebounceStart = () => { set(_currentValueAtom, nextValue); set(isDebouncingAtom, true); }; const onDebounceEnd = () => { set(debouncedValueAtom, nextValue); set(isDebouncingAtom, false); }; onDebounceStart(); if (!shouldDebounceOnReset && nextValue === initialValue) { onDebounceEnd(); return; } const nextTimeoutId = setTimeout(() => { onDebounceEnd(); }, delayMilliseconds); set(prevTimeoutAtom, nextTimeoutId); } ); const clearTimeoutAtom = atom(null, (get, set, _arg) => { clearTimeout(get(prevTimeoutAtom)); set(isDebouncingAtom, false); }); return { currentValueAtom: atom((get) => get(_currentValueAtom)), isDebouncingAtom, clearTimeoutAtom, debouncedValueAtom, }; }