Вы наверняка видели (или писали) такой код, чтобы избежать ошибки "Can't perform a React state update on an unmounted component":
// Антипаттерн
useEffect(() => {
let isMounted = true;
fetchData().then(data => {
if (isMounted) setState(data);
});
return () => { isMounted = false; };
}, []);
Это «мусорный» код. Запрос все равно происходит, трафик тратится, промис висит в памяти.
Вместо ручных флагов используйте стандартный браузерный API - AbortController.
Как сделать правильно:
useEffect(() => {
const controller = new AbortController();
fetch('/api/data', { signal: controller.signal })
.then(res => res.json())
.then(setData)
.catch(err => {
// Важно: не считаем отмену запроса ошибкой
if (err.name !== 'AbortError') {
console.error(err);
}
});
// При размонтировании или перезапуске эффекта запрос реально отменится браузером
return () => controller.abort();
}, []);
Бонус-фича: Очистка Event Listeners
AbortController умеет удалять и слушатели событий. Больше не нужно выносить функцию-хендлер в отдельную переменную, чтобы передать её в removeEventListener.
const controller = new AbortController();
// Передаем signal в опции
window.addEventListener('resize', (e) => handleResize(e), {
signal: controller.signal
});
// Одним вызовом удаляем слушатель (или группу слушателей с одним сигналом)
controller.abort();
Мы в MAX
@frontend_1