Muhammad Zulfan Wahyudin
Back to Blog
reactstate-managementarchitecture

Why I Stopped Using Global State Libraries

Between React Server Components, URL state, and context, most apps dont need Redux or Zustand anymore.

The Old Default

For years, dropping in Redux (or later Zustand, Jotai, Recoil) was the first step of every React project. The assumption was that components scattered across the tree need a shared bucket of state, and only a global store can provide that.

That assumption is worth questioning.

Three Things That Replace Global State

1. URL as State

Filters, pagination, search queries, selected tabs — all of these belong in the URL. Putting them in a global store means you lose browser history navigation, shareability, and the ability to deep-link.

// Instead of: store.setFilter('status', 'active')
// Do:
const [searchParams, setSearchParams] = useSearchParams();
const status = searchParams.get('status') ?? 'all';

2. Server State

Data from your API is not client state — it’s a cache of server state. Libraries like TanStack Query or the built-in use() hook with React Server Components handle loading, error, and stale-while-revalidate patterns better than any global store ever could.

Since React 19, you can fetch data directly in server components and pass it down:

// Server Component — zero JS sent to client
async function ProjectList() {
  const projects = await db.query('SELECT * FROM projects');
  return <ul>{projects.map(p => <li key={p.id}>{p.name}</li>)}</ul>;
}

3. Context for Truly Global Concerns

Themes, auth state, locale — these are legitimately global and affect the entire tree. React Context handles them well, and for most apps, one or two contexts are all you need.

When I Still Use Zustand

There is one case where I still reach for Zustand: complex client-side state that crosses component boundaries and changes frequently. A drag-and-drop board, a real-time collaborative document, or a multi-step form with validation across steps.

But that’s the exception, not the default.

The Balance

My rule of thumb now: start with URL params for UI state, server state libraries for data, and context for auth/theme. Add a global state library only when you can point to a concrete problem that the first three don’t solve.