Выбор ответа Middle Код-ревью обновлено

Гонка в загрузке

Вопрос

После исправления зависимостей код остался таким. Что ещё нужно исправить в первую очередь?

useEffect(() => {
  fetch('/api/users?q=' + encodeURIComponent(query))
    .then(r => r.json())
    .then(setUsers);
}, [query]);

Попробуйте сами

Выберите вариант, и откроется разбор.

Показать ответ и разбор

Коротко

Правильный ответ: Обработать гонку: отменять запрос в очистке через AbortController. При быстром наборе ответы приходят в произвольном порядке, и ответ на прошлый query может прийти последним.

Варианты ответа

  1. Заменить fetch на axios, он сам отменяет устаревшие запросы
  2. Перенести эффект в useLayoutEffect, чтобы ответы шли по порядку
  3. Добавить key на <List>, чтобы список пересоздавался на каждый ответ
  4. Обработать гонку: отменять запрос в очистке через AbortControllerправильный ответ

Разбор

При быстром наборе ответы приходят в произвольном порядке, и ответ на прошлый query может прийти последним. Очистка эффекта с controller.abort() (или флагом ignore) отбрасывает устаревшие ответы. Ещё стоит проверить r.ok. Замена HTTP-клиента гонку не решит. useLayoutEffect блокирует отрисовку и тут не нужен. key на списке не влияет на порядок ответов.

Ответьте сами, а не прочитайте

В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.