AbortController для очистки
Создавайте AbortController, передавайте его сигнал в fetch и отменяйте выполняющиеся запросы в функции очистки, чтобы предотвращать обновление состояния размонтированных компонентов.
«AbortController для очистки» — бесплатный урок Frontend Academy на CoddyKit. Это урок 4 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Frontend Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Frontend Academy содержит 4 уроков всего.
Зачем отменять запросы fetch?
Когда компонент размонтируется или повторно получает данные, предыдущий запрос может всё ещё выполняться. Если он завершится после нового запроса, устаревшие данные перезапишут свежие. AbortController аккуратно отменяет выполняющиеся запросы.
Основы AbortController
Создайте AbortController, передайте его signal в fetch и вызовите controller.abort(), чтобы отменить запрос. При отмене fetch выбрасывает AbortError.
const controller = new AbortController();
try {
const res = await fetch('/api/data', { signal: controller.signal });
const data = await res.json();
setData(data);
} catch (err) {
if (err instanceof DOMException && err.name === 'AbortError') {
console.log('Request was cancelled');
} else {
setError((err as Error).message);
}
}
// To cancel:
controller.abort();В очистке useEffect
Создайте AbortController в начале эффекта и вызовите abort() в функции очистки. Это автоматически отменит запрос при изменении зависимостей или размонтировании компонента.
useEffect(() => {
const controller = new AbortController();
async function load() {
try {
const res = await fetch(`/api/user/${userId}`, { signal: controller.signal });
if (!res.ok) throw new Error(`${res.status}`);
setUser(await res.json());
} catch (err) {
if ((err as DOMException).name !== 'AbortError') {
setError((err as Error).message);
}
}
}
load();
return () => controller.abort();
}, [userId]);AbortError и сетевая ошибка
Отменённый запрос выбрасывает DOMException с именем «AbortError». Всегда проверяйте именно этот случай и не показывайте его как ошибку, видимую пользователю, — это ожидаемое поведение очистки.
Свойство signal.aborted
Проверяйте controller.signal.aborted, чтобы узнать, была ли отменена сигнал. Это полезно, чтобы выполнить проверку перед вызовом setState в асинхронном коде.
const data = await fetchData();
if (!controller.signal.aborted) {
setData(data); // safe to update state
}Отмена нескольких запросов
Один AbortController может отменить несколько запросов fetch, если передать им один и тот же сигнал.
const controller = new AbortController();
const { signal } = controller;
await Promise.all([
fetch('/api/users', { signal }),
fetch('/api/products', { signal }),
fetch('/api/settings', { signal }),
]);
controller.abort(); // cancels all threeAbortController с Axios
Axios поддерживает signal AbortController через опцию signal в конфигурации. Интерфейс сигнала такой же, как у fetch.
const controller = new AbortController();
await axios.get('/api/data', { signal: controller.signal });
// In cleanup:
return () => controller.abort();React Query обрабатывает это автоматически
При использовании TanStack Query (React Query) отмена выполняется автоматически. React Query создаёт и отменяет объекты controller внутри себя. Это одна из причин предпочесть его ручным шаблонам запросов.
Настройка timeout с AbortController
Объедините AbortController с setTimeout, чтобы реализовать timeout запросов.
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 5000); // 5s timeout
try {
const data = await fetch(url, { signal: controller.signal });
// ...
} finally {
clearTimeout(timeoutId);
}AbortSignal.timeout() — современное сокращение
В современных браузерах AbortSignal.timeout(ms) создаёт сигнал, который автоматически прерывает запрос по истечении указанного времени, без ручного controller.
const res = await fetch('/api/data', {
signal: AbortSignal.timeout(5000) // 5 second timeout
});Критически важная очистка в строгом режиме React 18
React 18 в строгом режиме дважды монтирует эффекты в режиме разработки. Без очистки через AbortController Вы увидите двойные запросы и возможные предупреждения о попытках обновить состояние размонтированного компонента. Шаблон с очисткой предотвращает и то и другое.
Быстрая проверка
Как предотвратить обновление состояния устаревшим сетевым ответом после повторного рендера компонента?
Повторение: AbortController
Создавайте AbortController для каждого эффекта. Передавайте signal в fetch/axios. Вызывайте abort в функции очистки. Игнорируйте AbortError — это ожидаемо. Проверяйте signal.aborted перед setState в асинхронном коде. Один controller может отменить множество запросов. Используйте AbortSignal.timeout() для timeout. React Query обрабатывает всё это автоматически.
Часто задаваемые вопросы
Урок «AbortController для очистки» бесплатный?
Да — полный текст урока «AbortController для очистки» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Frontend Academy, подпишись на CoddyKit PRO. Курс Frontend Academy содержит 4 уроков всего.
Чему я научусь в уроке «AbortController для очистки»?
Создавайте AbortController, передавайте его сигнал в fetch и отменяйте выполняющиеся запросы в функции очистки, чтобы предотвращать обновление состояния размонтированных компонентов. Ты практикуешь Frontend Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Frontend Academy?
Предыдущий опыт не требуется. Frontend Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 4 из 4.
Сколько времени занимает урок «AbortController для очистки»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Frontend Academy?
Да. Каждый урок Frontend Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Основы useEffect: зависимости и очистка
- Загрузка данных при монтировании
- Обработка состояний загрузки и ошибки
- AbortController для очистки