JotaiJotai

상태
React를 위한 기본적이고 유연한 상태 관리

atomWithDebounce

atomWithDebounce는 상태 설정이 디바운스 처리된 아톰을 생성하는 데 도움을 줍니다.

이 유틸리티는 텍스트 검색 입력과 같은 상황에서 유용합니다. 여기서는 모든 키 입력마다 액션을 실행하는 대신, 일정 시간을 기다린 후 파생된 아톰의 함수를 한 번만 호출하고 싶을 때 사용할 수 있습니다.

import { atom, SetStateAction } from 'jotai'
export default function atomWithDebounce<T>(
initialValue: T,
delayMilliseconds = 500,
shouldDebounceOnReset = false,
) {
const prevTimeoutAtom = atom<ReturnType<typeof setTimeout> | undefined>(
undefined,
)
// 이 아톰을 사용하여 상태를 설정하면 currentValueAtom과 debouncedValueAtom 간의 상태가 불일치할 수 있으므로 EXPORT하지 마세요.
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,
}
}

주의사항

이 아톰은 React 18의 useTransitionuseDeferredValue와 같은 동시성 기능과는 다른 목적을 가지고 있습니다. 이들 기능은 주로 비용이 많이 드는 업데이트로 인해 페이지와의 상호작용이 차단되는 것을 방지하는 데 초점이 맞춰져 있습니다.

더 자세한 정보는 이 GitHub 토론에서 "How is it different from setTimeout?" 섹션을 참고하세요.

예제 사용법

아래 샌드박스 링크는 debouncedValueAtom의 값을 기반으로 상태를 가져오기 위해 파생된 아톰을 사용하는 방법을 보여줍니다.

<SearchInput>에 포켓몬 이름을 입력할 때, 모든 글자마다 get 요청을 보내지 않고, 마지막 텍스트 입력 이후 delayMilliseconds 시간이 지난 후에만 요청을 보냅니다.

이렇게 하면 서버로 보내는 백엔드 요청의 수를 줄일 수 있습니다.