防抖 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,
};
}