Видеоуроки, интерактивный редактор и сохранение прогресса — бесплатно, сразу после входа.
ВойтиСоздать аккаунт — бесплатноЗакончили урок?
Войдите, чтобы отмечать прогресс
В этом решении мы выносим состояние выбора письма в контекст: создаём MailContext, передаём в провайдер объект с selectedId и setSelectedId, а LetterRow и Viewer читают их через useContext. Промежуточный компонент Sidebar больше не принимает и не пробрасывает эти пропсы.
Контекст хранит и текущий выбранный id, и функцию обновления — так любой дочерний компонент может и прочитать выбор, и изменить его по клику. Имя MailContext отражает смысл: контекст почтового приложения (состояние списка писем).
Вместо пропсов selectedId и onSelect компонент получает оба значения из контекста. Активность строки вычисляется по selectedId, по клику вызывается setSelectedId(letter.id). Пропсы из родителя не нужны.
Sidebar принимает только letters — список для отображения. Он не знает про selectedId и onSelect и не передаёт их в LetterRow. Каждая LetterRow сама подписывается на контекст и обновляет выбор по клику.
Viewer больше не получает selectedId пропсом — он читает его из контекста и по нему находит письмо для отображения. Пропсы у Viewer убраны.
Состояние по-прежнему живёт в App через useState. Объект value для провайдера создаётся через useMemo с зависимостью [selectedId]: при том же selectedId ссылка на объект не меняется, поэтому потребители контекста не перерисовываются лишний раз. В провайдер передаётся только этот value; Sidebar и Viewer вызываются без пропсов выбора — они берут данные из контекста.