The previous post argued that most of what people put in a global store was never client state — it was server data, or URL state, or form values, all miscategorised.
That argument has a limit. Some applications genuinely have a lot of client state — editors, canvases, dashboards with cross-filtering, anything with undo, anything offline-first — and for those, "just use useState" stops being an answer.
Which is usually the point someone reaches for Redux, carrying a set of beliefs about it that mostly don't survive contact with why it was built. Worth taking apart one at a time.
Misconception 1: "It's a state manager"
Not really — it's an event log with derived state. The store isn't the primary thing; the sequence of dispatched actions is. State is just what you get from replaying that sequence from the start.
That framing sounds abstract until you see what it was replacing.
What 2015 looked like
Redux's design makes very little sense unless you remember what it was competing with.
Prop drilling was the only option. Context existed but was undocumented, marked experimental, and warned against. Getting a value from the top of the tree to the bottom meant threading it through every component in between, whether they cared or not.
There was no server-state story. No RSC, no query libraries. If your app needed data, you fetched it into component state and then dealt with every consequence yourself.
Nobody could explain why the UI was wrong. Two-way binding and scattered mutation meant state changed from many places, at many times, for reasons that were hard to reconstruct after the fact.
That third one is the important one. Redux was not primarily a solution to prop drilling — Context solved that. Redux was a solution to not being able to explain how the app got into this state.
Misconception 2: "The single store is an arbitrary rule"
It isn't arbitrary — it's the price of the thing misconception 1 just described.
Once you decide the goal is explicability, the design mostly writes itself.
If state is in one object, the app has one state. Not a set of overlapping fragments that might disagree — one value you can log, serialise, and inspect. "What is the app's state right now" has an answer you can print.
If every change is a described action, history is a list. { type: 'todo/added', payload } is a record of what happened, not of what you did about it. Replay the list from the initial state and you're back where you were.
Which makes time-travel debugging possible. State plus an ordered action list means you can step backwards and forwards through the app's history. That was the demo that sold Redux, and it does not work with state scattered across many independent stores — there's no single timeline to travel along.
And updates are atomic. One dispatch, one new state object, one notification. Two pieces of related state can't be briefly inconsistent because they were updated by two separate calls.
The single store isn't dogma or taste. It's what "the app has an inspectable, replayable history" costs.
Misconception 3: "Global state means Redux"
Redux calls itself a library for global state management, and it is one. The mistake isn't thinking it's for global state — it's thinking global is the property that tells you to reach for it.
It isn't. Plenty of global state has no business in Redux. A theme, a locale, the current user — global, and perfectly well served by Context. And a great deal of what people globalised into Redux was server data that was never client state in the first place, just cached remote data wearing a store's clothing.
The property that actually distinguishes Redux-shaped problems is traceability — state whose changes you need to log, inspect and replay, exactly the event-log design from the first misconception. Some global state needs that. Most doesn't. "Is it global" and "does it belong in Redux" are different questions, and conflating them is how a store ends up holding your entire app.
Which is visible once you look at what took each job away.
Almost every job Redux was doing in a typical CRUD app has been taken by something more specific.
Server data → the server. The largest use of Redux by volume was caching API responses: a posts slice, a users slice, loading flags, error flags, normalised entities, and reducers to keep it coherent. RSC removed the need for the copy, and post 7 established that mutations return a fresh tree rather than data you merge yourself. For apps that still fetch on the client, query libraries do this job better because they were designed for exactly it — caching, deduplication, revalidation, staleness.
Shareable state → the URL. Filters, tabs, pagination, search. Post 8's argument: if a colleague should see the same thing when you send them the link, it's URL state, and it never needed a store.
Passing values down → Context. Documented, stable, and adequate for values that rarely change. The original prop-drilling problem is just solved now.
Coordinated local state → useReducer. Actions and reducers, minus the store and the global scope. If you liked Redux's shape but never needed the globalness, this was always the thing you actually wanted.
What's left after those four is the honest scope of the question — and it's smaller than "global state" ever was.
Misconception 4: "Reducers are just ceremony"
They read that way until you need them. A reducer's actual job is making impossible states unrepresentable — { status: 'loading', data: null, error: null } as one value out of a named set, instead of three independent booleans that can disagree.
Once you accept that job, the "one store or many" question turns into a real trade rather than a style argument.
Atom-based state — Jotai, Recoil, and in a different way Zustand — breaks state into many small independent pieces. A component subscribes to the specific atoms it reads, and only re-renders when those change.
The upside is precision. No selectors to write, no worrying that a component re-renders because an unrelated slice changed, no single object growing without bound.
The cost is exactly what the single store bought. There's no one place to inspect. There's no single ordered history, so there's no time travel. Two atoms updated in sequence can be observed in an intermediate state. You've traded explicability for granularity — the same trade misconception 1 makes visible.
Your VDOM post's Signals section is the same trade at a different layer — fine-grained subscription instead of coarse re-render, precision in exchange for a single coherent pass you can reason about. Worth noticing that the industry keeps making that trade in the same direction.
Misconception 5: "Big app, therefore Redux"
Size was never the criterion. Traceability was. A large app made entirely of server data, URL state and forms needs none of this; a small app with a complex undo stack might need all of it. Concrete cases, not vibes:
Complex client state with real transitions. An editor where selection, tool, clipboard, zoom and dirty-status interact. The states that shouldn't exist are numerous, and a reducer is how you make them unrepresentable.
Undo and redo. If you need history, you need a single ordered list of changes. This is the case Redux's design was built for and nothing has replaced it.
Offline-first. A local source of truth that syncs when it can. That's a client-owned data store by definition.
Cross-cutting client state. State that many distant parts of the tree read and write, that isn't server data and can't live in a URL.
Genuinely hard debugging. If "how did it get like this" is a question your team asks weekly, an inspectable action log is worth its ceremony.
Redux Toolkit is what you'd actually use — the boilerplate that gave Redux its reputation is largely gone.
Misconception 6: "It's already in the project, so everything goes there"
This is the most common one in practice, and it's different from the other five — they're about what Redux is, this one is about what people do once it's installed. The reasoning is seductive: one place for state, one mental model, no per-feature debate about where things live. Consistency is a real virtue. This just spends it on the wrong thing.
Three versions of it, all worth catching.
"Anything used in several places should just go in Redux." Being read in many places is a real reason to lift state out of a component — that part's right. It just doesn't say Redux on its own, because "used widely" splits three ways. A value read in many places that rarely changes — a user profile, theme, locale — is Context's home turf; a Redux slice for it is a reducer, an action and a selector to move something that changes at login and logout. A value read and written in many places, changing often with real transitions, is the actual Redux case. And a value read everywhere that happens to be server data is still server data — the number of consumers doesn't make it client state. The profile is the trap here: it's almost always either cached server data or a stable widely-read value, and both have homes that aren't a store.
"All the localStorage stuff should hydrate into Redux." This turns one source of truth into two. The value now lives in localStorage and in the store, with a write path, a boot-time read path, and a bug waiting for the first time they disagree. localStorage already survives refresh — usually the only reason it was picked. Read it where you need it (useSyncExternalStore is the honest way) and there's one source of truth. Mirror it into Redux and there are two, plus a sync problem you now own.
"I don't use Context anymore, I have Redux." These aren't competing tools. Context is dependency injection — it moves a value down the tree. Redux is a state container. They're so much not-in-competition that Redux uses Context to hand you the store: <Provider> is Context. Dropping Context because you have Redux is dropping a delivery van because you built a warehouse. For a value that changes twice a year — theme, locale — Context alone is less machinery than a slice with its selector, action and reducer.
The error underneath all three is treating "already installed" as "is the answer." A tool's cost isn't the install. It's every future reader having to load your entire store into their head to understand one feature. A store holding server data, URL state, form values and localStorage mirrors isn't a state strategy — it's a junk drawer with a subscribe method.
The question to ask first
Before choosing a store, categorise what you're storing. Post 8's four owners: server, URL, form, ephemeral.
If most of it is server data, you don't have a state management problem. You have a caching problem — and a store is the wrong tool, because a store has no opinion about staleness, revalidation, or what happens when two tabs disagree. You'd be building a cache by hand, again, with a state library.
If most of it is genuinely client-owned, with complex transitions between pieces, then the question is real, and it's the narrower one this post has been about: do you need one inspectable history, or many precise subscriptions?
That's a decision you can actually make. "Should I use Redux" isn't.
If this helped, or if I got something wrong — find me on LinkedIn or my site. I read everything.