Выбор ответа Junior Эффекты и жизненный цикл обновлено

Фильтрация через эффект

Вопрос

Что не так с этим кодом?

const [visible, setVisible] = useState([]);
useEffect(() => {
  setVisible(todos.filter(t => t.done === showDone));
}, [todos, showDone]);

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

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

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

Коротко

Правильный ответ: Лишний state и лишний рендер: список нужно вычислять в рендере. Эффект срабатывает после коммита, поэтому сначала отрисуется устаревший visible, а затем будет второй рендер.

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

  1. Лишний state и лишний рендер: список нужно вычислять в рендереправильный ответ
  2. Ничего: так и нужно синхронизировать производное состояние
  3. filter нельзя вызывать внутри эффекта, только в обработчиках
  4. Нужно добавить setVisible в зависимости, иначе список отстанет

Разбор

Эффект срабатывает после коммита, поэтому сначала отрисуется устаревший visible, а затем будет второй рендер. Производные данные вычисляются в рендере: const visible = todos.filter(...), при дороговизне в useMemo. Вызов filter в эффекте допустим, просто не нужен. setVisible стабилен, добавлять его не обязательно, и проблему это не решит.

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

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