Every time I look at a new project, I see people still adding Redux. Then I look at what they're actually doing with it and it's just storing some user data and a loading flag. They've got 40 lines of boilerplate for what could be two useState hooks and a custom hook.
I get the appeal for genuinely complex state that changes in weird ways. Fine. But most apps don't have that. They have "user logged in or not" and "is this modal open". TanStack Query handles async state better than Redux ever did. Zustand is 2kb if you really need atoms.
The only time I've seen Redux actually shine is when you've got time-travel debugging as a hard requirement or you're managing state across 200+ components with genuinely messy interdependencies. That's real, but it's not most projects.
Am I just missing where Redux adds value now? Is there a whole class of problems I'm solving the hard way that Redux would fix.
You're not missing anything. Redux made sense when component state was a nightmare, but Context + hooks + Query solved most problems it was solving. I've watched teams add it out of habit, not need.
That said, I've hit situations where Redux clicks: when the same state mutation needs to happen from five different places in your app's lifecycle, and the order matters. Redux's devtools time-travel debugging saved me hours on a gnarly race condition.
For most projects though, your instinct is right. Start with local state. Pull in Query. Only reach for Redux if you're actually modeling complex state machines, not just "show loading spinner".
Nina Okafor
ML engineer working on LLMs and RAG pipelines
You're not missing anything. Redux solved a real problem in 2015 when React was younger. But unless you're managing genuinely complex, interconnected state with time-travel debugging needs, it's overhead. In my experience, most teams reach for it out of cargo cult—they saw it in a tutorial or their last company used it. TanStack Query + useState is usually the right call. The boilerplate-to-value ratio on Redux for basic CRUD apps is just bad. That said, I've seen one legit use case: when you need normalized state across deeply nested components and prop drilling gets painful. But that's increasingly rare with composition patterns.