Как спроектировать state
Вопрос
Как ты решаешь, что положить в state компонента, а что нет? Приведи пример ошибки.
Попробуйте сами
Ответьте вслух за 2 минуты, как на собесе. Потом сверьтесь с тезисами: что прозвучало, а что нет.
Показать ответ и разбор
Коротко
Что должно прозвучать в ответе
В state только то, что меняется со временем и не вычисляется из других данных
Производное считается в рендере, при дороговизне через useMemo
Не копировать props в state без явной причины
Хранить id выбранного элемента, а не копию объекта
Избегать противоречивых флагов: лучше одно поле status, чем isLoading и isError
Связанные поля держать вместе или выносить в редьюсер
Что могут спросить следом
- Как поступить, если нужно сбросить state при смене пропа?
- Где хранить данные с сервера?
- Когда state стоит поднять к родителю?
Разбор
Я исхожу из минимального набора данных, из которого всё остальное можно вычислить. Если значение выводится из props или другого state, считаю его прямо в рендере, иначе появляется второй источник правды и его нужно синхронизировать. Частая ошибка: хранить selectedItem как объект. Список обновился, а выбранный объект остался старым. Правильно хранить selectedId и находить элемент в рендере. Вторая ошибка: набор флагов isLoading, isError, isSuccess, которые могут оказаться одновременно true. Одно поле status с вариантами исключает невозможные состояния. Props в state копирую только как начальное значение и называю это явно, например initialColor. Если двум соседям нужны одни данные, поднимаю state к общему родителю. Серверные данные лучше держать в библиотеке кеша вроде TanStack Query, а не дублировать в локальном state.
Ответьте сами, а не прочитайте
В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.
Термины по теме
Ещё по теме «Состояние и useState/useReducer»
- Производное значение
- Стабильность dispatch
- Батчинг
- Ленивая инициализация state
- Функциональный апдейтер
- useReducer
- Апдейтер вперемешку со значением
- Ленивая инициализация