Ucieczka z pułapki: Naprawianie stale closures w React Hooks
Stale closures powodują cichą utratę danych w React.
Budujesz dashboard z timerem działającym w tle. Używasz setInterval wewnątrz hooka useEffect, aby automatycznie zapisywać dane co 5 sekund.
Błąd pojawia się w momencie uruchomienia interwału. Zapisuje on pusty dokument, nawet jeśli użytkownik wpisał całą stronę. Interwał pozostaje uwięziony w przeszłości – używa starej wersji stanu.
Problem
Gdy useEffect się uruchamia, przechwytuje zmienne znajdujące się w jego zakresie (scope).
- Jeśli pominiesz stan w tablicy zależności (dependency array), interwał będzie używał stanu z pierwszego renderowania.
- Jeśli dodasz stan do tablicy zależności, React będzie restartował interwał przy każdym naciśnięciu klawisza. To drastycznie obniża wydajność i psuje timing.
Rozwiązanie: Wzorzec Mutable Ref
Musisz oddzielić timer od danych. Użyj hooka useRef, aby zachować stałe odniesienie do swojego najnowszego stanu. Pozwala to uniknąć ponownych renderowań i utrzymuje interwał w stabilności.
Jak to zaimplementować:
- Utwórz ref, aby przechowywać najnowszy stan.
- Użyj
useEffect, aby aktualizować ten ref za każdym razem, gdy stan ulega zmianie. - Uruchom interwał z pustą tablicą zależności, aby wykonał się tylko raz.
- Uzyskaj dostęp do ref wewnątrz callbacku interwału.
Ta metoda zapewnia, że zadania działające w tle zawsze korzystają z aktualnych danych. Dzięki temu interfejs użytkownika pozostaje szybki, a dane bezpieczne.
Źródło: https://dev.to/iprajapatiparesh/escaping-the-trap-fixing-stale-closures-in-react-hooks-4gg7