Suggest an editImprove this articleRefine the answer for “Why isn't Context always suitable for global state?”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)**React Context is not a global store** - it is designed as a mechanism for passing data down the tree without prop drilling, not as a full state-management system. **Key point:** for small global flags (theme, language, current user) Context is great, while for complex business state Zustand, Jotai, Redux Toolkit, or React Query are a better fit.Shown above the full answer for quick recall.Answer (EN)Image## The key idea React **Context is not the same as a global store**, it is designed as a **mechanism for passing data down the tree without prop drilling**, not as a full-fledged state-management system. --- ## Why Context is not always suitable for global state ### 1. Every change to value re-renders all consumers When you write: ```javascript <MyContext.Provider value={{ user, theme }}> <App /> </MyContext.Provider> ``` React compares `value` **by reference**. If it has changed -> every component using `useContext(MyContext)` **re-renders**, even if the field it needs did not change. On a large tree, this causes cascading updates and lag. **Example:** `user.name` changes -> the whole UI using `theme` re-renders too. --- ### 2. There are no "selectors" (granular subscriptions) Context cannot subscribe a component **to only part of the data**. > If `value` holds `{ user, theme, cart }`, > then a change to `cart` updates even the components that only need `theme`. The workaround is to use third-party tools (`use-context-selector`, Zustand, Jotai), but "plain" Context does not provide this. --- ### 3. Every update goes through a React render Context is not optimized for **frequently changing state** (for example, a cursor, a timer, text input). At 60 updates per second, React simply cannot keep up. **Context is UI state**, not a "reactive stream". --- ### 4. There are no tools, middleware, or devtools Context: - has no devtools; - does not support time-travel; - does not make it convenient to log changes, roll back state, or debug business logic; - does not scale with a complex architecture. --- ### 5. Hard to scale as the app grows As the app grows, "crutches" start appearing: dozens of contexts (`AuthContext`, `CartContext`, `UIContext`, `SettingsContext`...), nested `Provider` trees, tangled dependencies, and "Provider hell": ```javascript <AuthProvider> <ThemeProvider> <UIProvider> <CartProvider> <App /> </CartProvider> </UIProvider> </ThemeProvider> </AuthProvider> ``` Hard to maintain, test, and extend. --- ### 6. Context is synchronous and local It is not designed for: - asynchronous requests (fetch/cache/retry); - syncing with a server; - offline data; - reactive subscriptions (WebSocket, SSE, etc.). For that, **React Query**, **Zustand**, **Redux Toolkit**, and others are a better fit. --- ## When Context is still ideal | Use case | Why it fits | |---|---| | Theme (light/dark) | Simple, rare change | | Interface language (i18n) | Updates only when the language is switched | | Current user | Changes only on login/logout | | Feature flags, settings | Small amount of data, low change frequency | | Compound components | Context is used as an internal communication bus (Tabs, Modal, Dropdown, etc.) | --- ## Alternatives for "real" global state | Task | Tool | |---|---| | Frequently changing state, business logic | **Zustand**, **Jotai**, **Redux Toolkit** | | Asynchronous data (fetch, cache) | **TanStack Query (React Query)** | | Reactive subscriptions, server pushes | **RxJS**, **useSyncExternalStore**, a custom store | | Simple static data | **Context** | --- ## Summary | Reason | Why Context does not fit | |---|---| | Frequent updates | All consumers re-render | | No selectors | You cannot subscribe to just part of the data | | No tooling | You cannot debug or control the flow | | Poor scalability | Provider hell and complex dependencies | | No asynchrony | Everything is synchronous and local | --- **Conclusion:** > Context is a mechanism for "passing data down the tree", > not a "global state store". > > For small global flags, it's great. > For complex business state, Zustand, Jotai, Redux Toolkit, or React Query are better.For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.