0Pricing
React Academy · Урок

Состояния гонки и очистка эффектов

Используйте AbortController в useEffect, чтобы отменять устаревшие запросы fetch при повторном рендеринге.

«Состояния гонки и очистка эффектов» — бесплатный урок React Academy на CoddyKit. Это урок 1 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения React Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс React Academy содержит 4 уроков всего.

Добро пожаловать

В этом уроке Вы узнаете, как возникают состояния гонки в эффектах React, которые получают данные, и как устранять их с помощью AbortController для очистки.

Что такое состояние гонки

Состояние гонки возникает, когда две асинхронные операции завершаются в непредсказуемом порядке. В React, если пользователь быстро переходит между элементами, медленный запрос для элемента A может завершиться после запроса для элемента B и показать устаревшие данные.

Ошибка: устаревший ответ запроса

Без очистки, если компонент повторно отрисовывается с новым ID до завершения старого запроса, выполняются оба запроса. Более старый и медленный запрос может перезаписать в состоянии более новые данные.
useEffect(() => {
  fetch('/api/item/' + id)
    .then(r => r.json())
    .then(data => setData(data)); // may run AFTER a newer fetch!
}, [id]);

Исправление 1: флаг ignore

Простое исправление: установите в эффекте логический флаг `ignore`. Функция очистки устанавливает для него значение true. Обратный вызов запроса проверяет флаг перед вызовом setState.
useEffect(() => {
  let ignore = false;
  fetch('/api/item/' + id)
    .then(r => r.json())
    .then(data => { if (!ignore) setData(data); });
  return () => { ignore = true; };
}, [id]);

Исправление 2: AbortController

AbortController — современный стандарт. Создайте controller в эффекте, передайте его сигнал в fetch и отмените запрос в функции очистки. Запрос вызовет ошибку AbortError, которую можно проигнорировать.
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 с async/await

Используйте конструкцию try/catch с асинхронными функциями внутри useEffect. Игнорируйте AbortError в блоке 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]);

Очистка обязательна всегда

Даже когда состояния гонки маловероятны, например при однократном запросе во время монтирования, всегда добавляйте очистку. В React 18 StrictMode эффекты запускаются дважды — без очистки первый оставленный запрос загрязняет состояние.

Особенность асинхронного useEffect

Обратный вызов useEffect не может быть `async`. Определите асинхронную функцию внутри эффекта и сразу вызовите её — или используйте обычную функцию с `.then()/.catch()`.
useEffect(() => {
  // useEffect callback is NOT async
  async function fetchData() { /* ... */ }
  fetchData(); // call it
  return () => ctrl.abort();
}, [id]);

Библиотеки делают это за Вас

React Query, SWR и RTK Query автоматически обрабатывают состояния гонки, операцию abort и очистку. При использовании этих библиотек Вам не нужно вручную писать код с AbortController.

Проверка состояний гонки

Чтобы вручную проверить состояния гонки, откройте сетевые DevTools, установите ограничение «Медленный 3G» и быстро переключайтесь между элементами. Без очистки Вы увидите вспышку устаревших данных. С AbortController отображается только последний выбранный элемент.

Быстрая проверка

Что делает вызов controller.abort() в функции очистки useEffect?

Повторение

Состояния гонки возникают, когда устаревший ответ запроса обновляет состояние после более нового запроса. Исправляйте это с помощью флага ignore или AbortController. Всегда отменяйте запрос или устанавливайте ignore в очистке useEffect. Библиотеки вроде React Query делают это автоматически.

Далее

Следующий урок: **useTransition для неблокирующих обновлений интерфейса** — Вы обернёте ресурсоёмкие обновления состояния в startTransition, чтобы интерфейс оставался отзывчивым.

Часто задаваемые вопросы

Урок «Состояния гонки и очистка эффектов» бесплатный?

Да — полный текст урока «Состояния гонки и очистка эффектов» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс React Academy, подпишись на CoddyKit PRO. Курс React Academy содержит 4 уроков всего.

Чему я научусь в уроке «Состояния гонки и очистка эффектов»?

Используйте AbortController в useEffect, чтобы отменять устаревшие запросы fetch при повторном рендеринге. Ты практикуешь React Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать React Academy?

Предыдущий опыт не требуется. React Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 1 из 4.

Сколько времени занимает урок «Состояния гонки и очистка эффектов»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке React Academy?

Да. Каждый урок React Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Состояния гонки и очистка эффектов
  2. useTransition для неблокирующих обновлений интерфейса
  3. useDeferredValue для устранения дребезга ввода
  4. Suspense для границ данных и кода
← Назад к React Academy