Ответ вслух Junior Код-ревью спрашивают часто обновлено

Ревью: производное состояние

Вопрос

Перед тобой код на ревью. Скажи вслух, что здесь не так - по убыванию важности.

Читай вслух, как на ревью: сначала что делает код, потом что сломано.

function Profile({ user }) {
  const [fullName, setFullName] = useState(user.first + ' ' + user.last);

  useEffect(() => {
    setFullName(user.first + ' ' + user.last);
  }, [user]);

  const [isAdult, setIsAdult] = useState(false);
  useEffect(() => {
    setIsAdult(user.age >= 18);
  }, [user.age]);

  return <div>{fullName} {isAdult && '18+'}</div>;
}

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

Ответьте вслух за 2 минуты, как на собесе. Потом сверьтесь с тезисами: что прозвучало, а что нет.

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

Коротко

Классика: то, что выводится из пропсов, положили в состояние и синхронизируют эффектами. Правильно - просто вычислить: Почему это не придирка.

Что должно прозвучать в ответе

  • производные значения не должны быть состоянием - их надо вычислять при рендере

  • лишний цикл рендера: сначала старое значение, потом эффект, потом новое

  • первый кадр показывает неверное значение isAdult

  • зависимость [user] по ссылке сработает, даже если поля те же

  • два эффекта и два состояния вместо двух строк вычисления

  • риск рассинхронизации, если где-то забыть обновить

Что могут спросить следом

  • А если вычисление дорогое?
  • Когда синхронизация пропса в состояние всё-таки нужна?

Разбор

Классика: то, что выводится из пропсов, положили в состояние и синхронизируют эффектами.

Правильно - просто вычислить:

const fullName = `${user.first} ${user.last}`;
const isAdult = user.age >= 18;

Почему это не придирка. Во-первых, лишний проход: React рендерит со старым значением, потом выполняет эффект, потом рендерит снова - пользователь может увидеть мигание, а isAdult в первом кадре вообще false независимо от возраста. Во-вторых, зависимость [user] сравнивается по ссылке: новый объект с теми же полями вызовет обновление зря. В-третьих, любое третье место, меняющее пользователя, обязано не забыть про синхронизацию - источник рассинхронизации.

Состояние нужно только тому, что нельзя вывести: ввод пользователя, ответ сервера, раскрытость блока.

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

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