Что такое глобальное состояние в React
Что проверяют
Умеете ли вы решить, какое состояние вообще должно быть глобальным, и знаете ли цену каждого инструмента. Сильный ответ отделяет серверные данные от клиентских и объясняет, почему Context не стейт-менеджер. Следом часто спрашивают, почему пол-приложения перерисовывается при смене одного поля в контексте.
Как отвечать
Глобальное состояние это данные, нужные многим компонентам в разных частях дерева: пользователь, тема, язык, корзина. Прежде чем выбирать инструмент, разделите состояние по природе:
- серверное: списки и карточки с бэкенда. Это кэш, ему место в TanStack Query, RTK Query или SWR: они сами дедуплицируют запросы, обновляют и инвалидируют данные;
- URL: фильтры, сортировка, номер страницы переживают перезагрузку, и ссылкой можно поделиться;
- локальное: поля формы, раскрытость блока остаются в
useStateрядом с компонентом; - клиентское глобальное: всё остальное, обычно его немного.
Инструменты для последнего:
- Context с
useStateилиuseReducer: встроен, хорош для редко меняющихся значений вроде темы. Любая сменаvalueперерисовывает всех потребителей, селекторов нет. В React 19 контекст читается и черезuse(Context), а провайдером служит сам<Context>; - Redux Toolkit:
configureStore,createSlice, DevTools, строгий однонаправленный поток. Уместен в больших командах со сложной логикой, старый Redux соswitchиconnectсегодня писать незачем; - Zustand: стор в несколько строк, подписка через селектор, перерисовывается только тот, чей кусок изменился;
- Jotai: состояние собирается из мелких атомов.
Внешние сторы подключаются к React через useSyncExternalStore, это защищает их от рассинхронизации при конкурентном рендеринге.
Где спотыкаются
Кладут ответы API в Redux или Zustand и вручную пишут загрузку, ошибки и инвалидацию, то есть заново изобретают кэш запросов.
Передают в провайдер value={{ user, setUser }} без мемоизации. Новый объект на каждом рендере перерисовывает всех потребителей, даже если данные не менялись.
Делают глобальным всё подряд, включая формы. Каждый введённый символ проходит через общий стор и задевает половину приложения.