Why I Still Use useContext Even When I Have Global State
Even with well-structured global state like Zustand or Redux, not all data should live globally. useContext helps introduce boundaries by scoping state to specific parts of the component tree, making features more isolated and easier to reason about. Itâs not a replacement for global state, but a way to control where state belongs.
At some point, it starts to feel like everything can just go into a global store.
User data? Store it.
Products? Store it.
Cart? Store it.
Especially when using something like Zustand or Redux, itâs easy to organize things cleanly:
useUserStore
useProductStore
useCartStoreEach feature has its own store. Everything looks modular. Manageable.
So the question naturally comes up:
If I can structure my stores well, why would I still need something like useContext?The Part That Was Missing
The issue isnât about how many stores you have.
Itâs about something more subtle:
where that state is allowed to exist
Global State Solves Structure
Splitting stores per feature is already a good step.
It solves:
- organization
- separation of concerns
- maintainability
Each store has a clear purpose.
But thereâs one thing it doesnât solve:
who is allowed to access it
The Problem With âEverything is Globalâ
Even with well-structured stores:
const user = useUserStore(state => state.user);This can be used:
- anywhere
- by any component
- at any time
Thereâs no restriction.
Over time, this leads to something subtle:
- unrelated parts of the app start depending on the same state
- changes in one place affect others unexpectedly
- debugging becomes harder (âwho changed this?â)
What useContext Brings Back
useContext doesnât compete with global stateâit adds something different.
It introduces scope.
<AuthProvider>
<Dashboard />
</AuthProvider>Now:
- only components inside this tree can access the auth state
- outside components donât even know it exists
Thatâs a boundary.
Why That Boundary Matters
Without boundaries, everything becomes connected.
With boundaries:
- features stay isolated
- logic is easier to reason about
- accidental coupling is reduced
Youâre not just organizing state anymoreâyouâre controlling its reach.
A More Practical Way to See It
There are actually two separate concerns:
1. How state is structured
- user store
- product store
- cart store
This is what global state tools help with.
2. Where state lives
- global â accessible everywhere
- scoped â limited to a part of the app
- local â inside a component
This is where useContext becomes useful.
When Global State Is Enough
Your approach works well when:
- state is truly shared across the entire app
- many features depend on it
- thereâs no need to restrict access
When useContext Makes More Sense
useContext becomes a better fit when:
- state belongs to a specific feature or page
- you want to limit access
- you want clearer ownership
Examples:
- auth inside a dashboard
- modal system inside a page
- form state across multiple steps
The Shift in Thinking
At first, it feels like a choice between tools:
Context vs Zustand vs Redux
But itâs actually a different question:
Should this state be global, or should it be scoped?
Final Takeaway
Using multiple stores solves organization.
Using useContext solves boundaries.
And both matter.
Because in the long run, the real problem isnât managing state.
Itâs making sure that state lives in the right placeâand only affects what itâs supposed to.