В эффекте создайте AbortController и отменяйте его в cleanup при смене userId; старому запуску запретите менять state.
Практическая задача: в React загрузить пользователя по userId через fetch и отменить предыдущий запрос, если userId изменился до завершения запроса.
В эффекте создайте AbortController и отменяйте его в cleanup при смене userId; старому запуску запретите менять state.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
В эффекте создайте AbortController и отменяйте его в cleanup при смене userId; старому запуску запретите менять state.
Пример hook для условного маршрута /api/users/{id}. Он возвращает данные только для текущего id; UI отдельно проверяет схему профиля.
import { useEffect, useState } from 'react';
function useUser(userId) {
const [state, setState] = useState(null);
useEffect(() => {
const controller = new AbortController();
let active = true;
setState({ userId, status: 'loading' });
(async () => {
try {
const response = await fetch('/api/users/' + encodeURIComponent(userId),
{ signal: controller.signal });
if (!response.ok) throw new Error('HTTP');
const data = await response.json();
if (active) setState({ userId, status: 'ready', data });
} catch {
if (active) setState({ userId, status: 'error' });
}
})();
return () => { active = false; controller.abort(); };
}, [userId]);
return state?.userId === userId ? state : { userId, status: 'loading' };
}
Предполагается непустой userId. Флаг защищает от позднего результата и ошибки отменённого запуска; отмена клиента не означает откат работы сервера.