Вопрос проверяет умение управлять жизненным циклом побочных эффектов и отменять неактуальные операции.
Cleanup-функция в useEffect позволяет отменить или игнорировать результат старого запроса, когда эффект больше не актуален. Она вызывается перед повторным запуском эффекта или при размонтировании компонента. Благодаря этому устаревшие запросы не могут обновить состояние. Это один из базовых способов защиты от race condition.
Cleanup-функция — это функция, возвращаемая из useEffect, которая выполняется при очистке эффекта.
useEffect(() => {
return () => {
// cleanup
};
}, []);
Сначала разберём идею на уровне логики.
Эффект запускает запрос
Зависимости меняются
React вызывает cleanup предыдущего эффекта
Старый запрос становится “неактуальным”
Новый эффект запускает новый запрос
Простой и часто используемый способ.
useEffect(() => {
let isActive = true;
fetch(`/api/search?q=${query}`)
.then(res => res.json())
.then(data => {
if (isActive) {
setResults(data);
}
});
return () => {
isActive = false;
};
}, [query]);
Здесь:
Старый эффект помечается как неактивный
Его результат игнорируется
State обновляется только актуальным запросом
Более “правильный” вариант для сетевых запросов.
useEffect(() => {
const controller = new AbortController();
fetch(`/api/search?q=${query}`, {
signal: controller.signal
})
.then(res => res.json())
.then(data => {
setResults(data);
})
.catch(err => {
if (err.name !== "AbortError") {
throw err;
}
});
return () => {
controller.abort();
};
}, [query]);
Он синхронизирован с жизненным циклом компонента
Работает при каждом изменении зависимостей
Позволяет явно управлять “актуальностью” эффектов
Cleanup-функция помогает решить race condition, отменяя или игнорируя устаревшие запросы. Это обязательный инструмент при работе с асинхронными эффектами в React.