use-debounced-callback
use-debounced-callback
주어진 함수의 디바운스 버전을 만드는 use-debounced-callback 훅에 대해 설명해 드릴게요. 마지막 호출 후 지정된 시간이 지날 때까지 실행을 지연해요. @mantine/hooks 패키지에서 제공돼요.
출처: 문서
본문
사용법
use-debounced-callback 훅은 주어진 함수의 디바운스 버전을 만들어요. 마지막 호출 후 지정된 시간이 지날 때까지 실행을 지연해요:
import { useState } from 'react';
import { Loader, Text, TextInput } from '@mantine/core';
import { useDebouncedCallback } from '@mantine/hooks';
function getSearchResults(query: string): Promise<{ id: number; title: string }[]> {
return new Promise((resolve) => {
setTimeout(() => {
resolve(
query.trim() === ''
? []
: Array(5)
.fill(0)
.map((_, index) => ({ id: index, title: `${query} ${index + 1}` }))
);
}, 1000);
});
}
function Demo() {
const [search, setSearch] = useState('');
const [searchResults, setSearchResults] = useState<{ id: number; title: string }[]>([]);
const [loading, setLoading] = useState(false);
const handleSearch = useDebouncedCallback(async (query: string) => {
setLoading(true);
setSearchResults(await getSearchResults(query));
setLoading(false);
}, 500);
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setSearch(event.currentTarget.value);
handleSearch(event.currentTarget.value);
};
return (
<>
<TextInput
value={search}
onChange={handleChange}
placeholder="Search..."
rightSection={loading && <Loader size={20} />}
/>
{searchResults.map((result) => (
<Text key={result.id} size="sm">
{result.title}
</Text>
))}
</>
);
}
flushOnUnmount 옵션
기본적으로 콜백은 컴포넌트가 언마운트될 때 실행되지 않아요. 컴포넌트가 언마운트되기 전에 대기 중인 콜백을 실행하고 싶다면 flushOnUnmount: true로 설정하세요:
import { useDebouncedCallback } from '@mantine/hooks';
const callback = useDebouncedCallback(
() => console.log('Hello'),
{ delay: 1000, flushOnUnmount: true },
);
leading 옵션
leading: true로 설정하면 첫 번째 호출에서 콜백을 즉시 실행하고, 그 후 delay 창 안의 후속 호출은 무시해요:
import { useDebouncedCallback } from '@mantine/hooks';
const callback = useDebouncedCallback(
() => console.log('Hello'),
{ delay: 1000, leading: true },
);
maxWait 옵션
maxWait를 사용하면 호출이 계속 도착해도 주어진 시간 창 안에 콜백이 적어도 한 번은 실행되도록 보장해요. 지속적인 입력 중 중간 결과를 원하는 search-as-you-type 같은 시나리오에 유용해요:
import { useDebouncedCallback } from '@mantine/hooks';
const callback = useDebouncedCallback(
(query: string) => fetchResults(query),
{ delay: 300, maxWait: 1000 },
);
Flush와 cancel
flush 메서드를 호출해 디바운스 콜백을 즉시 실행하거나, cancel로 대기 중인 호출을 버릴 수 있어요:
import { useDebouncedCallback } from '@mantine/hooks';
const callback = useDebouncedCallback(() => console.log('Hello'), 1000);
callback.flush(); // immediately executes the pending callback
callback.cancel(); // discards the pending callback
callback.isPending(); // returns true if a call is waiting to execute
정의
interface UseDebouncedCallbackOptions {
delay: number;
flushOnUnmount?: boolean;
leading?: boolean;
maxWait?: number;
}
type UseDebouncedCallbackReturnValue<T extends (...args: any[]) => any> = ((
...args: Parameters<T>
) => void) & { flush: () => void; cancel: () => void; isPending: () => boolean };
function useDebouncedCallback<T extends (...args: any[]) => any>(
callback: T,
delayOrOptions: number | UseDebouncedCallbackOptions
): UseDebouncedCallbackReturnValue<T>
내보내는 타입
UseDebouncedCallbackOptions와 UseDebouncedCallbackReturnValue 타입은 @mantine/hooks 패키지에서 내보내지므로 애플리케이션에서 import할 수 있어요:
import type { UseDebouncedCallbackOptions, UseDebouncedCallbackReturnValue } from '@mantine/hooks';
더 알아보기 (Learn more)
- use-counter — use-counter 훅
- use-debounced-state — use-debounced-state 훅