0Pricing
React Academy · Lekcja

Implementowanie własnego hooka useDebounce

Budować hook useDebounce opóźniający aktualizacje stanu do chwili, gdy użytkownik przestanie pisać

Implementowanie własnego hooka useDebounce to bezpłatna lekcja React Academy na CoddyKit. To lekcja 2 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej React Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs React Academy zawiera 4 lekcji w sumie.

Sygnatura hooka

Hook useDebounce przyjmuje wartość oraz opóźnienie w milisekundach i zwraca opóźnioną wersję tej wartości: function useDebounce(value, delay). Zwracana wartość debouncedValue jest opóźniona względem rzeczywistej wartości i aktualizuje się dopiero po upływie określonego czasu bez kolejnej zmiany.

Stan wewnętrzny debouncedValue

Wewnątrz hooka należy zadeklarować zmienną stanu: const [debouncedValue, setDebouncedValue] = useState(value). Stan ten przechowuje ostatnią zatwierdzoną wartość. Początkowo jest równy wartości początkowej i aktualizuje się dopiero po uruchomieniu timera debounce. Komponenty odczytujące debouncedValue otrzymują stabilną, ustaloną wartość wejściową.

useEffect z setTimeout

Główna logika znajduje się w useEffect: należy utworzyć timer za pomocą setTimeout(() => setDebouncedValue(value), delay) i zapisać jego identyfikator. Efekt uruchamia się za każdym razem, gdy zmieni się value lub delay. Timer zostaje uruchomiony delay milisekund po ostatniej zmianie i aktualizuje stan objęty debounce.

Czyszczenie timera w funkcji cleanup

Funkcja cleanup hooka useEffect wywołuje clearTimeout(timerId). Gdy value zmieni się przed uruchomieniem timera, React wykonuje cleanup i anuluje oczekującą aktualizację. Następnie planowany jest nowy timer. To kluczowy mechanizm działania debounce: szybkie zmiany stale resetują timer.

Zależności efektu

Tablica zależności useEffect powinna zawierać [value, delay]. Efekt uruchamia się ponownie za każdym razem, gdy zmieni się wartość wejściowa (dzięki czemu planowany jest nowy timer) oraz gdy zmieni się delay (na wypadek dynamicznego dostosowania interwału debounce przez wywołujący kod). Obie wartości muszą zostać uwzględnione, aby uniknąć problemów z nieaktualnym domknięciem.

Używanie hooka w komponencie

Użycie jest proste: const debouncedSearch = useDebounce(searchInput, 300). Osobny useEffect z [debouncedSearch] jako zależnością wykonuje wywołanie API. Stan wejściowy (searchInput) aktualizuje się natychmiast, dzięki czemu pole pozostaje responsywne; tylko wywołanie API czeka na debounce.

Przypadek brzegowy natychmiastowego pierwszego wywołania

Domyślnie standardowa implementacja działa tylko na trailing edge. W trybie „immediate”, który wywołuje funkcję przy pierwszym zdarzeniu, a kolejne wywołania obejmuje debounce, potrzebny jest ref śledzący, czy wywołanie już nastąpiło, oraz resetujący tę informację po upływie czasu oczekiwania. Jest to bardziej złożone rozwiązanie, ale przydatne w przypadku przycisków wysyłania.

Parametr generyczny TypeScript

W celu zapewnienia bezpieczeństwa typów hook należy zdefiniować jako generyczny: function useDebounce(value: T, delay: number): T. Dzięki temu TypeScript może wywnioskować typ debouncedValue na podstawie typu value. Parametr generyczny T automatycznie propaguje się przez stan wewnętrzny i typ zwracany.

Częsty błąd: brak funkcji cleanup

Częstym błędem jest zapomnienie o zwróceniu funkcji cleanup z useEffect. Bez cleanup każda zmiana wartości tworzy nowy timer, ale nigdy nie anuluje poprzedniego. W rezultacie uruchamia się wiele timerów, które wielokrotnie wywołują setDebouncedValue z nieaktualnymi wartościami, całkowicie niwecząc działanie debounce.

Porównanie z podejściami opartymi na useRef

Alternatywą jest przechowywanie samej funkcji debounce w useRef z użyciem lodash. W przeciwieństwie do podejścia opartego na stanie podejście z refem obejmuje debounce callbacków (funkcji), a nie wartości. Podejście oparte na stanie należy wybrać, gdy potrzebna jest wartość pochodna, a podejście z callbackiem — gdy debounce ma dotyczyć handlera zdarzenia.

Weryfikacja działania w praktyce

Działanie hooka można zweryfikować, dodając logowanie konsolowe wewnątrz callbacku timera i obserwując konsolę przeglądarki podczas szybkiego pisania. Powinno pojawić się jedno logowanie na każde zdarzenie „stop”, a nie jedno na każde naciśnięcie klawisza. Podczas szybkiego pisania liczba logów powinna być znacznie mniejsza niż liczba naciśnięć klawiszy.

Czyszczenie useEffect w useDebounce

Dlaczego useEffect w useDebounce musi zwracać funkcję cleanup, która wywołuje clearTimeout?

Podsumowanie lekcji: hook useDebounce

Hook useDebounce(value, delay) przechowuje stan objęty debounce, który aktualizuje się dopiero po delay ms ciszy. Jego useEffect ustawia timer i usuwa go podczas cleanup, aby anulować nieaktualne timery. Wartość objętą debounce należy wykorzystać jako zależność efektów pobierających dane z API. Dodanie generycznego typu TypeScript zapewnia pełne bezpieczeństwo typów.

Często zadawane pytania

Czy lekcja „Implementowanie własnego hooka useDebounce” jest bezpłatna?

Tak — pełny tekst „Implementowanie własnego hooka useDebounce” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu React Academy, przejdź na CoddyKit PRO. Kurs React Academy zawiera 4 lekcji w sumie.

Co nauczysz się w „Implementowanie własnego hooka useDebounce”?

Budować hook useDebounce opóźniający aktualizacje stanu do chwili, gdy użytkownik przestanie pisać Ćwiczysz React Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć React Academy?

Nie wymagamy żadnego doświadczenia. React Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 2 z 4.

Ile czasu zajmuje lekcja „Implementowanie własnego hooka useDebounce”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji React Academy?

Tak. Każda lekcja React Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Dlaczego debounce i throttle są ważne w interfejsach
  2. Implementowanie własnego hooka useDebounce
  3. Implementowanie własnego hooka useThrottle
  4. Zastosowania praktyczne: wyszukiwanie, przewijanie, zmiana rozmiaru
← Powrót do React Academy