Ревью: производное состояние
Вопрос
Перед тобой код на ревью. Скажи вслух, что здесь не так - по убыванию важности.
Читай вслух, как на ревью: сначала что делает код, потом что сломано.
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 ошибок.
Предыдущий вопрос
Ревью: загрузка по поисковому запросу
Следующий вопрос
Ревью: запрос с идентификатором организации