Как обойтись без менеджера состояния в React?
Контекст и State managers
Обойтись без стейт-менеджера можно почти всегда, если правильно разделить типы состояния и использовать встроенные средства React плюс кеш запросов.
Разделить состояние по природе
- Серверные данные (списки, профиль, заказы) — это кеш, а не состояние приложения: TanStack Query / SWR. Дедупликация, фоновые обновления, инвалидация. Именно эта категория раньше и раздувала Redux.
- URL-состояние (страница, фильтры, поиск, выбранный таб) — держать в адресной строке: useSearchParams/роутер. Бонус: ссылки шарятся и переживают перезагрузку.
- Локальный UI (открытость модалки, ввод, hover) — useState рядом с местом использования.
- Редкие глобалки (тема, текущий пользователь, локаль) — Context с мемоизированным value.
- Форма — React Hook Form, а не глобальный стор.
После такого разбора «глобального состояния» почти не остаётся.
Инструменты React, заменяющие стор
- Подъём состояния к общему родителю + композиция (children/слоты) вместо prop drilling.
- useReducer + Context — «Redux без Redux» для поддерева: централизованные переходы, стабильный dispatch. Разделять контексты (данные и dispatch отдельно), чтобы не будить лишних потребителей.
- useSyncExternalStore — если нужен свой мини-стор с точечными подписками, без библиотеки.
Когда стор всё же нужен
Много несвязанных потребителей часто меняющегося клиентского состояния (редактор, канбан, realtime-корзина), нужна история действий/девтулзы, сложные кросс-модульные правила. Тогда лёгкий Zustand обычно достаточен.
Коротко для собеседования
Разложить состояние: серверное — в React Query, навигационное — в URL, локальное — в useState рядом с компонентом, редкие глобалки — в Context (мемоизированный value), формы — в RHF. Для поддерева — useReducer + Context, для своего стора — useSyncExternalStore. Стейт-менеджер остаётся для сложного часто меняющегося общего состояния.