Redux is still by far the most widely used state management tool with React apps (my estimates are around 45-50% of React apps use Redux), and we try to give clear guidance in our docs on when it does and doesn't make sense to use Redux.
FWIW, we get highly positive feedback on a daily basis from users who tell us how much they love using Redux Toolkit.
Resources:
- https://blog.isquaredsoftware.com/2018/03/redux-not-dead-yet...
- https://blog.isquaredsoftware.com/2021/01/context-redux-diff...
- https://blog.isquaredsoftware.com/2021/05/state-of-redux-may...
- https://blog.isquaredsoftware.com/2021/05/learn-modern-redux...
- https://blog.isquaredsoftware.com/2017/05/idiomatic-redux-ta...
- https://redux.js.org/tutorials/index
- https://redux.js.org/tutorials/essentials/part-2-app-structu...
I can't speak to his code contributions, but in terms of documentation, tutorials, and community engagement, most open source projects would be lucky to have similarly prolific contributors.
FWIW I _have_ written actual code in the libraries too :) I wrote React-Redux v7 by myself, shepherded the design of our hooks API in 7.1, and did all the coding work for v8. Also created Redux Toolkit, added a couple additional APIs, and a bunch of other stuff :)
A bit sad that immer was used (a bit too much magic for my taste), but I can understand the reasoning, and if you just accept it, it's ok.
Thank you and all the other maintainers for your work!!!
- Too much "magic" as you said
- Proxy-wrapped data values can be harder to inspect in the browser's debugger
- Seeing "mutating" code may be confusing
I understand those, but from my perspective the benefits of Immer far outweigh any potential negatives.
Ultimately all Immer does is track attempted mutations to nested data, and replay them to create the immutable updates as if you'd done all the nested spread operators yourself. There were dozens of immutable update libs in the ecosystem already (I had listed most of them in my Redux addons catalog), and accidental mutations have always been the number 1 cause of bugs in Redux apps. So, a better way to write immutable updates was clearly valuable.
Immer drastically simplifies all that update logic:
- Removes all the extra object spreads and slices and concats you would have had to write previously, so the code is much shorter and easier to read. It's also more clear what the actual intent of the state update is.
- It also completely eliminates accidental mutations _in_ reducers, and also _out_ of reducers by freezing the state.
So, shorter code, easier to read, and eliminates the #1 cause of Redux bugs.
The tradeoffs are a couple KB of bundle size (which is quickly paid for by having shorter reducers), and needing to understand that Immer is there and doing this "magic" for you.
The one still slightly nagging annoyance is that inspecting Proxy-wrapped data in a debugger is painful, but Immer does supply a `current()` util to extract the plain JS data if you need to, and we document doing that:
https://redux-toolkit.js.org/usage/immer-reducers#debugging-...
So, as with all tools Immer isn't 100% perfect, but it was absolutely the right choice to include it in RTK by default.
But as I said, I still highly recommend Redux Toolkit. After dealing with the code using MobX and the complexities brought by its reactions, I would take Redux anytime. Immer is just a small unfortunate detail, but I can live with it.
You still have to understand Redux's weird boiler plate concepts - actions, action creator functions, reducers, thunks, ... - to understand and use Redux toolkit. Redux is broken from the bottom up.
Note that I would never (again) use thunk - using such side effects leads to unmaintainable code, at least in my experience.
It won't ever be a one-size-fits-all solution and unfortunately, Redux will have to live with the legacy of plenty of users finding that out the hard way.
That being said, I think Redux Toolkit is a great improvement to the vanilla experience and I'm always impressed by how much I see you out and about on the internet weighing in on these kinds of threads. Inspiring stuff!
Using the redux-toolkit and the hooks, with none of the additional junk is a great experience.
I have respect for what acemarke writes above and I think acemarke is right that redux has been overused a whole lot.
The biggest thing I miss in react ecosystem is decent redux ORM. https://vuex-orm.org is just so great for so many use cases (agree that it might an antipattern in many situations). Is there any chance that https://github.com/redux-orm/redux-orm, which was actually what inspired vuex-orm, would get more love from anyone to become an actively maintained library?
Thanks
At the time, the main benefits to using Redux-ORM were easier immutable updates for items in the store, keeping items in a normalized state structure, and managing relationships between items for both lookups and updates.
Since then, Redux-ORM has changed maintainers and had its API tweaked. Meanwhile, we added a `createEntityAdapter` API [0] to RTK, which handles normalization and some CRUD-style updates to the data. Even without those CRUD helpers, you can still do `state.entities[itemId].someValue = 123` thanks to Immer, so immutable updates are taken care of.
At this point, the one remaining thing that Redux-ORM really handles that RTK doesn't is that specifically relational behavior - ie, given a `Post`, look up all its `Comment`s by an array of IDs or something. You can do a decent amount of that with selectors, but yeah, Redux-ORM's API here is nicer.
We haven't tried to provide any of that ourselves because this becomes a much more complicated and app-specific topic. But, I'm always open to suggestions for APIs and use cases. If you have ideas for things that we should consider adding to RTK, please do file an issue so we can discuss details!
These are all obviously _very_ imperfect proxies for actual usage stats, but they're all that I see available to work with.
FYI my last attempt to estimate "React state management market share" was in a Reddit thread earlier this year, with download numbers and caveats included:
https://www.reddit.com/r/reactjs/comments/lcgqnd/state_manag...
That's not a bad thing (and it's better than the alternative of not caring for design patterns whatsoever). It's part of the learning process, and since there are so many beginner developers who are using React, their perspective is much 'louder' than in other dev ecosystems.
You can see this in the absurd amount of introductory-level React content posted to Medium, DevTo, Twitter, etc. This has bred a very strong 'follow-the-leader' culture where, when the one person is the room who _does_ know what they're talking about makes a statement, others will repeat it verbatim without understanding its nuances due to a lack of experience/context.
Redux suffered heavily from this. New React devs in 2017 were faced with mountains of tutorials which all used Redux. Many of these tutorials were written by other newbies. Your mental model of React dev was then shaped around Redux. Therefore you would put everything you could into the Redux store, which is a bad idea -- you usually don't need form state in there, for example.
Then some React thought-leaders saw this problem and inadvertently created a counter-movement by raising how Redux was overkill for some use cases, which was misconstrued as 'you shouldn't use redux _at all_'. The pendulum has been swinging back and forth ever since.
Yes, not every application needs separation of concerns. But some definitely do. It's not black and white, and that unfortunately means there's no definable 'best practice' that can be tweeted or blogged about and followed blindly -- it just has to be learned from experience.
Or maybe more accurately, discovering that it's often simpler to separate by concern at the component level, than at the app level.
We all ride the pendulum until we find the shade of grey which works best for us.
Like, I don't want _everyone_ to use Redux. I just want people to understand "here are the strengths, weaknesses, and use cases of tools X, Y, and Z, and when it may make sense to use them".
Honestly, we Redux maintainers (Dan, myself, Lenz Weber) have had to spend far more time telling people when _not_ to use Redux than we have trying to advertise the library :)
When I rewrote the Redux docs tutorials last year, I made it a point to put "When should I use Redux?" right up front on the first page:
https://redux.js.org/tutorials/essentials/part-1-overview-co...
but that sadly can't have any effect on the thousands of existing tutorial pages or low-effort posts that are out there already.
Why's that? IME it is usually simplest to just put everything in redux. For example, if you have a form under some kind of tab navigation thing, you'd ideally want the form state to be preserved even when they tab out and then back in. Putting it in redux means you don't really have to think about it
You'd still preserve on tab change just as easily, while using just reacts mental model.
For any project that I'm responsible for, I don't feel comfortable designing around a paradigm unless there are some guard rails to prevent developers on my team from accidentally tying the code in knots. How enjoyable is this for the developers? Are they sprouting angel wings and playing the lyre as they write code in iambic pentameter? Probably not, no. They have less freedom of motion than if they were left to their own devices.
This is a larger debate: where to fall on the spectrum between unadulterated developer bliss and having an application that is still maintainable in 5 years. I don't put much stock in developer bliss, but I do appreciate that the sword cuts both ways.
The churn in the frontend ecosystem reminds me a lot of fad dieting: people have never really experienced working in a paradigm that enables them to stay healthy through regular diet and exercise over the long term, so they turn to the latest shiny gizmo hoping that this time it will be different.
I've been reading "blue" DDD book (by Eric Evans) and "red" book (by Vaugh Vernon) and that was a completely "my whole life was a lie" type of experience and relief at the same time. It's just so great to have the principles of who to structure the code. It, by definition makes, your codebase structure meaningful. Because it's structured according to some common knowledge, not your random thoughts at the time you were writing code.
I was surprised to find so little DDD react sample codebases. Let's say for backend there is huge amount of samples, i.e. https://github.com/kgrzybek/modular-monolith-with-ddd . For react/frontend I have bookmarked only https://github.com/talyssonoc/react-redux-ddd/tree/master/sr... and few more, but those others does not meet the optional criteria i like really much - at the highest (or at app) level all codebase need to have folders app, domain, infra and ui. Simple rule, but simplifies life a lot.
So my question is - is DDD for some reasons not very applicable for app frontend development. Or it just never became popular. Or maybe DDD is popular amongst react developers, just I am not aware of this.
Many thanks for any ideas and comments!
It won the Flux wars, but there are state management approaches based on paradigms other than flux. There's at least the model that Recoil/Jotai uses (atoms?), the model that MobX/Valtio uses (mutable observable state), the model based on state machines (XState), the model heavily using React context (Constate), etc.
I like (and use) Redux on a daily basis, and I don't think it's a sensible choice for lots of React apps. Maybe the overwhelming rejection that I've witnessed is people discovering that they used it for stuff they shouldn't have.
The React ecosystem has spent the last few years trying a model where the application layer separated from the view layer with a pure functional state management solution called Redux. The overwhelming response? People didn't like it.
Decoupling systems is a trade-off. Pull your network requests out of your components and you have two bits of code that are easier to test. Indirectly, the component is still going to call that code, and it's up to you to manage the complexity of that indirection.
Not every application needs separation of concerns, and in many, colocation of concerns reduces the cognitive burden, because you can reason about components in isolation. To me, that's a more powerful guarantee than a function being strictly pure.