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

Объект в зависимостях

Вопрос

Почему соединение переподключается после каждого рендера, хотя roomId не меняется?

const options = { serverUrl, roomId };
useEffect(() => {
  const conn = connect(options);
  return () => conn.close();
}, [options]);

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

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

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

Коротко

Правильный ответ: options создаётся заново на каждом рендере, ссылка новая. Зависимости сравниваются через Object.is, а литерал объекта в теле компонента это новая ссылка на каждом рендере.

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

  1. connect нельзя вызывать в эффекте, только в обработчиках
  2. Нужен useLayoutEffect, он сравнивает зависимости глубоко
  3. Эффекты перезапускаются при каждом рендере родителя
  4. options создаётся заново на каждом рендере, ссылка новаяправильный ответ

Разбор

Зависимости сравниваются через Object.is, а литерал объекта в теле компонента это новая ссылка на каждом рендере. Решение: создать options внутри эффекта и зависеть от roomId. useLayoutEffect сравнивает зависимости так же. Рендер родителя сам по себе эффект не перезапускает, если зависимости не изменились.

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

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