0Pricing
React Academy · Lekcja

Warunki wyścigu i czyszczenie efektów

Używanie AbortController w useEffect do anulowania nieaktualnych żądań fetch podczas ponownego renderowania.

Warunki wyścigu i czyszczenie efektów to bezpłatna lekcja React Academy na CoddyKit. To lekcja 1 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.

Wprowadzenie

W tej lekcji dowiedzą się Państwo, jak powstają race conditions w efektach React pobierających dane oraz jak je eliminować za pomocą AbortController używanego do sprzątania.

Czym jest race condition?

Race condition występuje, gdy dwie operacje asynchroniczne kończą się w nieprzewidywalnej kolejności. W React, jeśli użytkownik szybko przechodzi między elementami, powolny fetch dla elementu A może zakończyć się po fetchu dla elementu B i wyświetlić nieaktualne dane.

Błąd: nieaktualna odpowiedź fetch

Bez sprzątania, jeśli komponent wyrenderuje się ponownie z nowym identyfikatorem, zanim zakończy się stary fetch, oba zapytania będą wykonywane. Starszy, wolniejszy fetch może nadpisać nowsze dane w stanie.
useEffect(() => {
  fetch('/api/item/' + id)
    .then(r => r.json())
    .then(data => setData(data)); // may run AFTER a newer fetch!
}, [id]);

Sposób 1: flaga ignorowania

Proste rozwiązanie: w efekcie należy ustawić booleanową flagę `ignore`. Funkcja sprzątająca ustawia ją na true. Callback fetch sprawdza flagę przed wywołaniem setState.
useEffect(() => {
  let ignore = false;
  fetch('/api/item/' + id)
    .then(r => r.json())
    .then(data => { if (!ignore) setData(data); });
  return () => { ignore = true; };
}, [id]);

Sposób 2: AbortController

AbortController to współczesny standard. Należy utworzyć kontroler w efekcie, przekazać jego sygnał do fetch, a następnie przerwać operację w funkcji sprzątającej. Fetch zgłosi wtedy AbortError, który można zignorować.
useEffect(() => {
  const controller = new AbortController();
  fetch('/api/item/' + id, { signal: controller.signal })
    .then(r => r.json())
    .then(data => setData(data))
    .catch(err => {
      if (err.name === 'AbortError') return; // expected
      setError(err.message);
    });
  return () => controller.abort();
}, [id]);

AbortController z async/await

W funkcjach asynchronicznych należy użyć try/catch wewnątrz useEffect. AbortError należy zignorować w bloku catch.
useEffect(() => {
  const ctrl = new AbortController();
  async function load() {
    try {
      const res = await fetch('/api/' + id, { signal: ctrl.signal });
      const json = await res.json();
      setData(json);
    } catch (e) {
      if (e.name !== 'AbortError') setError(e.message);
    }
  }
  load();
  return () => ctrl.abort();
}, [id]);

Sprzątanie jest zawsze wymagane

Nawet gdy race conditions są mało prawdopodobne, na przykład przy jednorazowym fetchu podczas montowania, zawsze należy dodać sprzątanie. W React 18 StrictMode efekty są uruchamiane dwukrotnie — bez sprzątania pierwsze porzucone żądanie zanieczyszcza stan.

Pułapka asynchronicznego useEffect

Callback useEffect nie może być `async`. Należy zdefiniować funkcję asynchroniczną wewnątrz efektu i natychmiast ją wywołać — albo użyć zwykłej funkcji z .then()/.catch().
useEffect(() => {
  // useEffect callback is NOT async
  async function fetchData() { /* ... */ }
  fetchData(); // call it
  return () => ctrl.abort();
}, [id]);

Biblioteki robią to za Państwa

React Query, SWR i RTK Query automatycznie obsługują race conditions, przerywanie operacji i sprzątanie. Przy korzystaniu z tych bibliotek nie trzeba ręcznie pisać kodu z AbortController.

Testowanie race conditions

Aby ręcznie przetestować race conditions, należy otworzyć Network DevTools, ustawić ograniczenie sieci na 'Slow 3G' i szybko klikać między elementami. Bez sprzątania będą widoczne krótkie mignięcia nieaktualnych danych. Z AbortController wyświetli się tylko ostatnio wybrany element.

Szybkie sprawdzenie

Co powoduje wywołanie controller.abort() w funkcji sprzątającej useEffect?

Podsumowanie

Race conditions występują, gdy nieaktualna odpowiedź fetch aktualizuje stan po nowszym fetchu. Można je naprawić za pomocą flagi ignorowania lub AbortController. W funkcji sprzątającej useEffect zawsze należy przerwać operację albo zignorować jej wynik. Biblioteki takie jak React Query robią to automatycznie.

Następna lekcja

Następna lekcja: **useTransition for Non-Blocking UI Updates** — opakują Państwo kosztowne aktualizacje stanu w startTransition, aby zachować responsywność interfejsu.

Często zadawane pytania

Czy lekcja „Warunki wyścigu i czyszczenie efektów” jest bezpłatna?

Tak — pełny tekst „Warunki wyścigu i czyszczenie efektów” 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 „Warunki wyścigu i czyszczenie efektów”?

Używanie AbortController w useEffect do anulowania nieaktualnych żądań fetch podczas ponownego renderowania. Ć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 1 z 4.

Ile czasu zajmuje lekcja „Warunki wyścigu i czyszczenie efektów”?

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. Warunki wyścigu i czyszczenie efektów
  2. useTransition do nieblokujących aktualizacji interfejsu
  3. useDeferredValue do opóźniania obsługi danych wejściowych
  4. Suspense dla granic danych i kodu
← Powrót do React Academy