Сравни способы общения между компонентами и объясни, когда выбирать каждый вариант.
Компоненты
Способ общения компонентов выбирается по их взаимному положению в дереве и по характеру данных.
Родитель ↔ ребёнок: props и колбэки
<SearchInput value={query} onChange={setQuery} />Вниз — props, вверх — вызов переданного колбэка. Выбирать всегда, когда компоненты соседствуют по вертикали: самый явный и дешёвый способ.
Соседи: подъём состояния
Состояние переносится к ближайшему общему родителю; один сосед пишет (колбэк), другой читает (props). Выбирать для локальных связок вроде «фильтр + список». Если общий родитель слишком далеко — признак, что нужен контекст или стор.
Сквозь много уровней: Context
const theme = useContext(ThemeContext);Выбирать для редко меняющихся «окружающих» данных (тема, пользователь, локаль, DI сервисов). Не выбирать для частых обновлений: все потребители перерендериваются при любом изменении value.
Многие-ко-многим: стейт-менеджер
Zustand/Redux/MobX — стор вне дерева, точечные подписки селекторами, централизованная логика. Выбирать, когда состояние общее для многих несвязанных частей приложения и часто меняется (корзина, realtime-данные, сложные формы-визарды).
Серверные данные: React Query / SWR
Общий кеш запросов: два компонента, запросившие одни данные, получат один запрос и синхронное обновление. Выбирать для всего, что приходит с сервера, — вместо протаскивания через стор.
Императивные случаи: ref
useImperativeHandle + ref (в React 19 — обычный проп, до 19 — через forwardRef) — родитель вызывает методы ребёнка (фокус, reset, скролл). Выбирать точечно, когда декларативно выразить неудобно.
Коротко для собеседования
Вертикаль — props/колбэки; соседи — подъём состояния к общему родителю; сквозь уровни редкие данные — Context; общее динамичное состояние — стейт-менеджер с селекторами; серверные данные — React Query (кеш, а не пропсы); императив — ref. Начинать с простейшего (props) и усложнять только по необходимости.