One underrated thing that I miss from using Redux is the "action trace". You can literally sit down with the stakeholders [1] and explain the exact things that caused a screen to render. And these things are not cryptic function calls with stack-traces, but simple and chronologically ordered sets of human readable "actions" (I like to think of them as events) like UserFetched -> PlanFetched (<with this data>) -> FrozenUser. One can rewind the actions and iterate with the stakeholders why that screen appeared. This is huge and I miss this a lot.
1. Note that most of the time the stakeholder is yourself and/or another developer. But can also definitely be a non-coder.
It's worth noting that the Redux DevTools Extension _can_ capture and display a literal stack trace for every dispatched action, if you've enabled that while setting up your store. This allows you to see what part of your app triggered each state update:
I was about to ask what kind of stakeholder gives a damn about sitting down with you and going through an action trace to see why a certain screen rendered, but I’m glad you added the note at the bottom.
Regardless, yourself or another developer as the “stakeholder” in this scenario is a bit of a cop out. In the real world stakeholders aren’t technically inclined and even if they are they don’t care about this minutiae.
Please start thinking of "stakeholder" as everyone who has a stake in a project. This includes those who have to maintain the code and those who have to operate the service. Thinking this way will help ensure requirements gathering includes all stakeholders.
No, I keep a very mercenary mentality when it comes to projects. I’m told what needs to be done and I do it and get paid for it. Early on in my career I cared too much, and it brought nothing but unnecessary stress. I will never sit down and watch a redux stack trace, it’s not my job and I got better things to do.
No, and I don’t imagine I’ll write much more about it than these few comments.
I think a lot of developers start off the same way. Idealistic, starry eyed recruits eager to put their knowledge to use and make a product better than they found it.
But then you realize life’s too short to bother with things like Redux. We’re not building software to last thousands of years, there’s no future archaeologists who are going to spelunk through our ancient code and be in awe at the ingenuity of our primitive minds.
We’re lucky if we’re writing software that lasts a couple quarters. Especially when you’re building front end UI, you can expect whatever you do to be completely bulldozed by whatever trend or framework comes along.
So don’t care. It’s not your job, you’ll be paid regardless. If someone wants me to care about a project, they need to pay me extra. Because caring forces that project to take up space in my mind and takes attention and focus from other things I actually want to care about, such as getting my work done and meeting objectives. Early on I used to care so much it would actually interfere with my ability to get things done in a timely manner.
And when co-workers turn around and shit on you for slowing them down, and you see they don’t care either and still get the same pay and recognition, or maybe even more in some cases, you realize there’s no point. That’s not how this business works. Don’t be a hero.
By now I’m so experienced with React I don’t need some time travel debugging tool to tell me shit, even with very complex state. I never have. If I run through an error a few times and throw some console logs I can quickly find and solve the problem 99% of the time. A valuable skill.
I was tempted to say something like ‘are you recently out of college or a bootcamp? What stakeholder are you impressing here with a Redux stack trace?’.
I tried to avoid it but your post just brought out it of me.
In the vast majority of React apps you do not need this.
I work on an app that has a total of about 400 separate Redux actions across half a dozen reducers and a couple of stores. There's a lot of things that cause side effects. Being about to see what actions fired with various props is immensely useful for debugging. redux-devtools and Reactotron are immensely useful. You're right that the majority of React apps don't need to trace actions, but when you do you definitely won't think it's overrated.
Can you give me an example how you got to 400 actions? Just enumerate like 5 or so, I’m assuming you are building features where groups of actions are just necessary based on the patterns you are using.
I’m genuinely curious because I feel like this kind of inflation of actions/reducers in Redux is what makes it nightmarish.
For one thing they do encourage a lot of tiny actions. A frequent pattern I use requires three actions for every server call: one to trigger a saga, one when it succeeds, and one for when it fails.
The standard form is incredibly verbose, I've started to shift away from it.
Note that the new `createAsyncThunk` API in Redux Toolkit handles generating and dispatching the promise lifecycle actions for you [0]. Also, while sagas are a great power tool, most Redux apps don't need them [1].
Awesome! It's great to finally have some links to share.
The company I'm currently working with is the first time I've used sagas / observables / "anything async is through side effects". I've constantly been saying "this is madness, this giant block of code, all these concepts, all this room for things to go wrong, just to do a `fetch`?". It's also the first time in a few years of using redux I've had to deal with race conditions.
Edit: Oh, and you can even `await dispatch`! All the things I've been doing in Redux for years and told I shouldn't, now being officially endorsed.
Can you give me an example how you got to 400 actions?
I'm not going to go in to detail on HN, but the app I work on is used to make diagrams for the legal industry and to define how they change over time. It's sort of like Visio for lawyers, with a basic animation editor that understands the underlying data. There are a lot of actions simply because it does a lot of things that can't be generalised in to higher level actions (well, they could, but it'd be messy.)
Have you used it? That’s like saying the Chrome debugger or CPU call stacks are overrated. It’s a debug feature that any React+Redux app can use to trace back why something happened. I’ve used it a few times, and when you need it because you don’t understand why an action was triggered, it’s super convenient.
any application that you need to debug, I have not ran into a application React or not that I didn't need to debug and Redux does help with debugging greatly.
I first wrote it back in 2018, and just updated it yesterday with some additional links and comparisons.
(Actually was considering retitling it after getting some feedback last night, but given that the link just got submitted here, I'll leave it as-is for now.)
A few quick notes:
- If you haven't looked at Redux in a while, please try out our official Redux Toolkit package [0], which is now our recommended approach for writing Redux logic, and the React-Redux hooks API [1]. We're going to be teaching both of those as the default approach for using Redux going forward.
- We have a new "Style Guide" docs page that gives our official guidance on suggested usage patterns [2]
- On that note, I'm working on an ongoing major rewrite of the Redux core docs [3]. My current task is creating a new "Quick Start" tutorial, which will be a "top-down" intro to using Redux to stand alongside the existing "bottom-up" tutorial sequence. The goal of the Quick Start section is to quickly introduce Redux concepts, and show RTK and hooks as the "right way to write Redux code", without going into the details of how it works under the hood, so that folks can get started now and learn the underlying aspects later. I've an early partial WIP draft PR up [4], and hope to finish the first draft in the next few days. Once the Quick Start page is done, I'll be turning my attention to rewriting the main tutorial sequence in order to remove outdated terms, clarify explanations, and teach simpler patterns (like using "ducks" files instead of splitting code across multiple files).
If anyone's got questions on anything I wrote in the article or otherwise Redux-related, ask away!
That was a great article—wish I had read it back in 2018! I'll chime in with some thoughts, as someone who has built several apps using React/Redux.
What's happened with me (and others I've seen) has been discovering Redux, falling in love, and thinking "I'll use it for everything!" There's something about the simplicity of having a single state tree, that is immutable and debuggable that just blows your mind.
Then you start building, and after writing your Xth action/reducer/selector/dispatch/etc, you tire of the boilerplate and the overhead.
So where I've landed is:
1) we use Apollo/GraphQL for data-fetching and caching.
2) we use hooks in general.
3) for deeply nested component communication, we haven't fully settled on whether to use redux or not and kind of mix it up depending on the circumstance
4) we use redux when we need app-wide state and/or debuggability (so everything that's not 1, 2, or 3).
This has worked pretty well for us, though (3) is still a little fuzzy.
Anyway, I do think Redux is awesome, so thanks for maintaining it. But just wanted to chime in that I think a lot of "Redux is dead" sentiment (besides just being article click-bait and sensationalism by publishers) is actually people realizing that they've done the "everything is a nail" thing and retreating a little bit from that.
Yeah, as I tried to make clear in the post, there's many other excellent tools and libraries in the ecosystem, and they _do_ overlap with the kinds of use cases that might have made people pick Redux in the past.
For the record, I've never wanted _everyone_ to use Redux, and I agree with criticisms that Redux has been frequently over-used.
All I want is for folks to look at their use cases, take the time to evaluate tools, and make intelligent decisions about what tools best solve their problems.
Unfortunately, the nature of social media and the development community just doesn't seem to work that way. No one seems to write posts saying "here's a new tool, here's how it compares to existing tools, and here are the tradeoffs involved and the use cases where they might each be relevant". It's always "LOL TOOL X IS DEAD NOW!", even if Tool Y is brand new and has 10 downloads and 2 GH stars while Tool X's daily downloads continue to increase.
Thanks for sharing this, is interesting to hear what other folks are doing in practice!
We were actually thinking of migrating to something similar in terms of data fetching to Apollo/graphql and leaving redux for more app wide state problems.
Could you share any further insights on how you started organising this project? I.e. some pieces in Apollo/graphQL while maintaining a redux core, (presumably that's the core you started with?). Would be really interested.
Also I share your sentiment exactly, redux isn't dead. It's still a really solid approach to state management, and in complex applications I still think it's one of the best options. Thanks and kudos to the maintainers!
I’ve been loving redux toolkit so far, so great job on that! The docs are super good too, so props for wanting to improve them further.
I encourage everyone to try out redux toolkit if you feel like redux is too much boilerplate. It also comes with immer out of the box, so no more crazy spread operators.
Do you, or anyone else in the team or community, have a good resource you would recommend to people complaining about "too much boilerplate" in redux code? It is likely the most common complaint I see, that I understand to come from a place of people not understanding it this a tool best used for scaling and/or already big projects. Whenever I have worked with Redux in a large project, that "boilerplate" is minimal and the benefits obvious.
Yeah, as I talked about in both the original blog post and my parent comment, we've specifically designed Redux Toolkit to eliminate the "incidental complexity" that came along with using Redux [0]:
- Immer makes writing immutable updates easy, because you can write "mutating" logic like `state.todos[5].completed = true`
- `configureStore` sets up a Redux store with good defaults (DevTools extension, thunks, mutation checking) in a single line of code and has easier-to-read options if you do need to tweak the config
- `createSlice` eliminates the need to write any action creators or action types by hand
- Our new `createAsyncThunk` and `createEntityAdapter` APIs (new in v1.3.0 [1]) simplify the common use cases of dispatching actions as part of data fetching and managing normalized data in your state
Also, RTK is written in TypeScript, and designed to infer as much as possible. For example, if you declare the type of the action payload in a `createSlice` reducer, the generated action creator has its payload argument typed automatically to match.
Meanwhile, the React-Redux hooks API generally requires less code than `connect` does, and is easier to use with TypeScript as well.
Finally, we're now encouraging folks to use the "ducks" pattern for single-file Redux logic [2], which cuts down the number of files you might have to work on for a given feature, and using `createSlice` basically gives you ducks files for free [3].
I think that complaint usually comes from people who try to put everything related to state in Redux, and not just the parts of it that need to be.
Also the 'reducks' pattern of splitting the Redux state into separate files, each containing a reducer and the related actions and selectors helps keep things simple to understand (although I guess it is a bit more overhead, actually).
What are the obvious benefits other than fundamentally dumping shared data into a global singleton?
How do you handle testing of connected components? There’s tons of pain points. I’m on a pretty large Redux project too, and every day I wish I could just simplify the whole app (as we scale) by removing Redux.
I don't know if I agree... I've used "traditional" Redux in very large projects and the boilerplate far from minimal, and it grows in the same scale the app grows. And it's in the parts that grow more, which is app code: action types and action creators are very un-DRY and repetitive. Switch statements are way noisier syntatically compared to other solutions such as classes or objects (used in VueX and RTK createSlice). Etc.
I think it speaks volumes when the Redux maintainers are going into a direction that uses less boilerplate, like Redux Toolkit.
Honestly, there's nothing wrong with boilerplate, but I guess it's time to admit that some people love it and others hate it.
I think it's important to distinguish between the "inherent" complexity" and "incidental" complexity in using Redux [0].
Dispatching actions and writing reducers is _inherent_ complexity. It's part of Redux's design, and is a deliberate level of indirection.
Having to write nested spread operators to perform immutable updates, switch statements in reducers, and `const ADD_TODO = "ADD_TODO"` is _incidental_ complexity. Nothing about Redux's core design _requires_ you to write the code that way. There's valid reasons why those patterns exist [1], but writing a reducer with a switch statement vs a lookup table doesn't change how the Redux data flow behaves.
My goal is to eliminate the incidental complexity, because it's not necessary and does present a barrier to people learning and using Redux.
I found I was just using Redux as a data caching layer and ended up using SWR hooks instead https://swr.now.sh/. This has resulted in way less boilerplate (which increases even more with a type system) and a better development and user experience for the product I was working on. For everything else I use context like managing modals, auth, errors, and firebase connections.
I love Redux but I am very frugal about what I put into the store and have come up with a strong set of design patterns with my team to know what should and should not go there. That, in conjunction with hooks for any other stateful concerns we have, makes for a sane and pleasant dev experience.
IMO the biggest and best draw of Redux is how it allows you to completely separate your business logic from your UI layers. Your components only know about props and state and are rather trivial to test. Hooks are great for re-usable logic as well but my team made the choice to have hooks deal only with localized state concerns and have a robust Actions => Services => Reducer layer for everything that speaks to things outside that constraint. Its worked out wonderfully so far. Tests are a breeze and logic is highly portable. Our UI layer is thin and easy to change.
Its not all roses of course. The Redux store can turn into a rats nest of keys and values with no obvious structure (or worse, duplicated structures). It's something that requires actually sitting down and modelling out your data structures. Sadly that's something I don't see very often (and I am just as guilty as anyone else). The Redux team came up with some good guidelines on this point (too lazy to track the link down but its on the main site) and I think they have some really good ideas. I think more than anything its important to consider your store in the same manner you would a database and approach it with that kind of mindset. As with all things JS, its easy to dive in, hard to untangle yourself! :)
We've recommended normalizing data as a pattern for years [0], but never had any official tooling to support that use case. Redux Toolkit 1.3 now has a new `createEntityAdapter` API that can help with the process of inserting and updating normalized data [1].
I do kind of violate this... I tend to use action creators that will accept an event from a component, and use e.target.dataset.someValue as necessary... it's not exactly a violation... but it's muddy... having clean action handler syntax in my Components though it better imho.
I use createActionsHook below in every actions.js file... combined with thunks, it's awesome imho.
IMO the only downside to your approach is that it couples your action creators to the calling component. That isn't necessarily a bad thing but it all depends on what your particular goals are. If you intend to have your action creators as a kind of "super prop" that is specific to your caller and disposable and single purpose in nature, I think that works. To be successful (again IMHO) you'd want to segregate your business logic outside of that layer into either the reducer (as the redux team recommends) or in a service layer that the actions can talk to (my preferred approach). As always YMMV.
Oh, the results are handled by the reducer... it's not that far off.. expecting an event with a given shape, as opposed to a direct argument. Can even be split, one for the view specifically another for the more pure actioncreator... with the thunks+async function, it's easy to have a start, await api call and finish/error events dispatched.
So many great things about redux that are hard to mimic...
- the ability to create a middleware that is your analytics listeners. Analytics will listen to actions and spit out analytic info when those actions trigger. Because of this there is literally no analytics code anywhere in your codebase, except encapsulated in that one analytics middleware and sub-tree.
- Ability to just see every state update in dev tools which is AMAZING for tracking down what caused a non-obvious problem. For example: Was it a bad api request? Was it a bug in the reducer? etc. Hard problems suddenly become easier with good debugging tools.
- Ability to persist a part of the store to local storage. This is actually quite nice.
One thing I like is that it's really easy to put a client library (for, say, some REST service) behind a combine-reducerable Redux store and a few exposed "action creators" (event emitters). Especially if you're using TypeScript so all that stuff's easy to find and understand. Anyone familiar with Redux will be able to use it immediately, and it'll work just fine anywhere JavaScript does (provided whatever other packages the client lib depends on will work on a given platform) including places you might want, for good reasons, to use JavaScript but lean on some UI system other than React (Apple TV, say, or maybe Electron).
I don’t like the structure Redux forces my apps into. This might be a good opportunity to see what simple solutions people are using to avoid stuff like Redux. I remember reading about this:
I am inclined to agree. At first I thought Redux was awesome, but eventually discovered that there is a lot of boilerplate and just a general overhead to doing certain things.
However, I definitely fall into the cluster of people that were "just told to use Redux". For my next React project I will certainly evaluate other approaches.
I taught a course on Javascript in undergrad with a unit on react as well as redux (cis.upenn.edu/~cis197, check it out!). To this day, I still think people learning JS should know about redux because of the design pattern it encourages (note that when people are first learning CS, this is probably the first-ish time they're coming across the concept of a reducer and "functional" state that isn't mutated directly).
I think it's even more important for people self-learning react to be exposed to redux in some way; yeah, there's boilerplate, but it's just beautiful when all put together and isn't a Blackbox (I love dan's tutorial on egghead explaining redux from the ground up precisely because it breaks down exactly what's working and why it is).
This blog post does an excellent job of convincing newcomers in the JS world to consider learning redux. I'm definitely forwarding this to the current instructor of the course!
I've recently tried using Redux for a side-project. While it solves the problem (organizing state), I feel there is too much boilerplate for my small project.
Are there any popular alternatives which don't use reducers?
EDIT: thanks for all the responses, I'll check them out :)
You can use a React Context and have simple global state in your React app. If you like reducers, throw in a useReducer hook and you have a large part of what people use Redux for.
I've done that recently, and I had many performance issues. I have a long-ish list of very simple components that are in a sorted order. So when I change the value of one, I re-sort the list. I was hoping React would only rerender the changed items (remove old, insert new). But no, it rerenders the whole list, which takes 500ms. I made sure object references in the list stay the same, that didn't help.
I can implement this thing in vanilla JS, and it would not take more than a few milliseconds. React is cool, but so damn hard to optimize.
It's important to distinguish between React "rendering" (asking components what they want the UI to look like), and actually applying updates to the DOM.
React's default behavior is that when a component renders, React will recursively re-render _all_ of its descendants. it then diffs the VDOM render output to see if you've asked for any changes to the UI since the last time it updated. If the two VDOM trees are the same, React says "nope, nothing to do here!", and ends the render pass. _If_ you requested changes, it then gathers them up and applies them all to the DOM in one step.
You can optimize the rendering behavior in some ways if needed. The `React.memo()`, `PureComponent`, and `shouldComponentUpdate` APIs [0] allow you to tell React to skip re-rendering if you know that a component's props haven't meaningfully changed, and thus would result in the same UI output as the last time. This does require that the child components be separate component types (ie, `<MyComponent />`), not just the parent rendering a bunch of plain elements (like `<div>`).
For lists in particular, React needs to know how to identify which items are which. React doesn't care about object references, but you can pass a special prop called a `key` when rendering items in a list. That way, if you move a list item up, swap a couple others, delete one, and add a couple more, React knows what existing list items ended up where, and can update the DOM efficiently in response. Otherwise, changes to lists without good use of keys can result in more DOM work being done than actually necessary.
I've recently had success using https://github.com/rematch/rematch for a small project. Significantly less boilerplate, though admittedly the documentation is a bit sparse.
I had a similar problem when I started using Redux for a side project. If it's a simple enough app (as mine was) try https://www.npmjs.com/package/unstated. I am not a React expert but this was super simple and easy to get up and running with.
Also check out mobx-state-tree...made by the same people and more suited towards large applications.
I personally love mobx-state-tree (and mobx!). I really wish more would not jump straight for redux/etc without giving the powerful abstraction of observables via mobx a shot.
hooks and the context api are great for small projects. Check out the hooks comparison section in the linked article to understand how it might fit your app. It references other good resources, too.
I agree ... I recently went back to using Redux in a project and I'm loving it. Redux at its heart is just a state manager, but because people tie it to React I've gotten people tell me all sorts things about how you don't need it anymore with all its new features.
I think the addition of React's hooks and context api actually make Redux easier to use, and I like the purity of its role as a state manager. I personally find that its cleaner to keep the overall application state in redux than to hold onto it inside of React, and leave react to manage its own component's state regarding ui level interactions.
I don't like how this article moves the goal posts of whether redux fits our use case or not. It has some valid arguments (dev tools) but the overhead of the boilerplate and tooling around redux is just not worth it IMO.
Much better to break your app state into various custom hooks that leverage Context API and the `useReducer` hook.
Not sure what you mean by "moving the goalposts" here.
I'm trying to make a few specific points:
- Redux is not "dead" in the sense that it is still widely used and is continuing to be adopted
- There are definitely many other tools in the React ecosystem that overlap with how you'd use Redux, but the Venn diagrams for the use cases don't entirely match up, and the other solutions don't necessarily have all the capabilities of Redux
- Redux _has_ been over-used and put in apps where it didn't fit well, and I want people to only use it when it makes sense to do so
- Our Redux Toolkit library and React-Redux hooks API make it a lot easier to use Redux
‘ - Redux _has_ been over-used and put in apps where it didn't fit well, and I want people to only use it when it makes sense to do so’. ‘
There are developers working day in and day out in these Redux codebases so our feedback is coming from a real place. There’s a million articles that pushed Redux to the top and got it used in just about everything. Articles just like this one.
This article is literally pushing back against all the reasons why Redux might not be a good fit. There’s very little in it that goes ‘yeah you know what, for this scenario, don’t use Redux’.
- I have no control over the millions of other tutorials that have been written. I can only control my own blog, and the actual Redux docs.
- The question of "When does it make sense to use Redux?" has been answered numerous times already [0] [1] [2]
- I wasn't trying to address the "when?" question in this article. I was trying to answer "is Redux still a viable choice, and how does it compare to other alternatives?"
I've written plenty of 6-10K word blog posts about Redux before that delve into how and when to use it. That wasn't my goal for this post.
There is an odd dynamic that happens in tech: A framework or approach exists for a specific purpose; that framework is used badly or inappropriately by devs who don't fully understand it; those same devs spread the idea that said framework is bad/difficult/insecure and people who use it just don't know what they're doing; some of those devs happen to be "thought leaders" and use their platform to broadcast their misunderstanding as gospel
CSS, SASS, redux, array.reduce, webpack are examples that come immediately to mind from the javascript world. There have been so many throughout the years
So it’s difficult to parse what your observation is providing insight into.
So let’s see how this blame game works, because I have a hunch you want to aim it at people that think Redux is a bad choice.
You are suggesting that people that really don’t like Redux actually don’t know how to use it properly, misuse it, go down that rabbit hole and come out completely jaded by it. They then go on to provide their feedback, to which the obvious dismissive response is ‘well maybe you don’t know what your’re doing’. So the bad mouthing is actually occurring from the other side, no?
For the last few years, any job post you saw related to React, Redux was a prerequisite for probably over 90% of those posts. In other words, Redux was gospel, not the the feedback of naysayers. The mass broadcasting was happening by the framework adopters to the point said framework became ubiquitous.
Lastly, there’s very little feedback about Redux that has to do with people’s understanding of it. Almost the entirety of feedback is coming from usage of Redux and noticing by-products of using it (bloated code base, needless complexity - and this needless complexity criticism is ripe for being sniped by the framework advocates as a symptom of essentially incompetent developers who can’t see the elegance of Redux. The feedback is that it’s not elegant ).
The thought leaders are not the people providing negative feedback in this thread and elsewhere. The thought leaders, the gospel creators in this case are these Redux based articles/advocates that prolifically spread Redux throughout the React ecosystem to the point it became a standard dependency for every app.
In this case, this is a very real situation where it needs serious push back because it spread untethered and unexamined.
One thing I also want to point out, the same way the developer community has a responsibility to evaluate the proper usage of a technology, those who partake in pushing certain technology also have a responsibility of analyzing the impact of what they are evangelizing. One could argue it is irresponsible for influential subsets of the Javascript ecosystem to push a layer of complexity for apps that do not need to make the trade offs for a few features.
@runawaybottle, with sincere respect, you projected a lot of meaning into what I wrote: "You are suggesting that people that really don’t like Redux actually don’t know how to use it properly, misuse it, go down that rabbit hole and come out completely jaded by it."
Nope. Neither implied nor intended.
The article is a reasonable reaction by a redux maintainer to the dynamic I describe. "I don't like using Redux" is a totally valid opinion. "Redux is terrible" is, frankly, not a valid opinion. Neither is it valid for CSS, javascript, React, Vue, Pascal, COBOL nor what-have-you, and yet here we are yet again, letting fickle winds of fashion and facile opinion dictate what should be engineering decisions.
Use redux if your use case applies. Don't use redux if it doesn't. If you find it unwieldy, dont use it. I wish the tech community could leave it there, but they don't.
I'll point out that the Redux team (first Dan Abramov and Andrew Clark, now myself and Tim Dorr) never tried to market Redux as something you _must_ use, and in fact have had to actively spend lots of time telling people to _not_ use it all the time. (Probably one of the only tools in existence where the maintainers have spent more time _discouraging_ its use than _encouraging it, which is a state of affairs that frustrates me to no end.) We've continually tried to provide guidance in the docs as to when it _does_ make sense to use it.
But, as I noted just above this comment: we don't control the rest of the developer ecosystem. All we control is the official docs, and our own blogs and social media comments.
I also want to emphasize that we _haven't_ dismissed people's feedback as "you don't know what you're doing", and in fact have tried to take that feedback into account with our docs and the creation of Redux Toolkit, to guide people in the right direction as they use Redux.
Redux is great, and I'm glad to see all this cleared up, to some extent. Especially the bit about the new context API somehow eliminating the need for Redux. I know some people don't like redux and that's fine - don't use it. But it's still super-useful to many, many people.
We all don’t get to waltz into a new job and say ‘Hey remove all this verbose Redux code and app structure, it’s slowing down velocity. Plus this crud app is too simple to add this annoying layer of boilerplate’.
Redux always had to much boilerplate for me to prefer it.
The last couple years I have been using the new Context API and spliting my app state out by creating a global context, and many ___domain specific contexts where the context contains both the data and functions used to work with that data. Typescript + state with data and functions created a great api per ___domain. I found this approach just as clean but with less boilerplate.
Though redux does have some performance and tooling benefits.
I disagree... I use useSelector, and now all my actions.js files export a default useActions method with a wrapper I wrote...
Yeah, the boilerplate setting up the middleware and initial reducer isn't fun... but it's been really rewarding and the react-redux hook has been a godsend.
Cool, but I tend to use sessionStorage as a backup to the store to re-hydrate on reload... I also use the thunks plugin so that I can have actioncreators that do multiple dispatches.
Sunk cost, these people have spent hundreds of hours learning something that ultimately is going to be discarded even more. That's why people are downvoting.
No, I downvoted because all the comments amount to X bad Y good. What they are posting has nothing to do with the article. The article even specifically talks about most of the Ys that are getting commented about and address what use-cases they are for that Redux isn't for. It's clear those people are not here to talk about the thing they are commenting on, they are just here to tell everyone they don't like Redux.
I have yet to be given a good usecase for Redux. All I see is code that ends up causing issues:
- redux pollution (not cleaning up state and things leaking)
- because you can't access redux state directly, components have to copy redux state and store them as props (which makes 0 sense, its state not props). But now you run into the issue where the local prop is not in sync with redux since redux updates are correctly done in chunks.
What do you mean by "can't access Redux state directly" and "copy Redux state"? Neither of those sounds correct.
Components have always been able to extract whatever data they want from the store using the `connect` API, and now our new `useSelector` hook. Those APIs return whatever values _you_ want for use in the component, and that generally is the actual object references to the real data that's in the store.
Both `connect` and `useSelector` subscribe to the store and re-run the logic you've provided whenever the store is updated, and force a re-render of your component with that fresh data. If I have:
const user = useSelector( state => state.users.entities[props.userId])
Any update to that specific `user` object in the store will cause this component to re-render. Same goes for `connect` and `mapState`.
So yeah, your statement confuses me, because it doesn't seem to describe how React-Redux actually works.
Right, and I'm saying that both `mapState` and `useSelector` perform the same behavior: allowing your component to subscribe to portions of the Redux store state, extract that, and update the component when that data changes.
So, I don't understand what points your parent comment is trying to make, because the whole point of React-Redux _is_ to keep your components in sync with the data in the Redux store state.
We have run into several issues where a user clicks a button (which updates redux) and then quickly clicks on something else and the 2nd component has not been updated yet as it used the mapState prop (the update is being batched by redux and hasn't gone out yet to the listeners).
Switched to using a shared model class instance - the value is changed immediately and anyone who needs to know the latest version can do it easily. Much simpler, faster and easier to debug since there is truly only one source of truth, not copies everywhere.
That sounds very surprising. Yes, React-Redux does batching and cascades updates through the UI layer, but that process should happen extremely quickly (far faster than the amount of time needed for someone to click on another button).
I'm also not sure why you keep using the phrase "copies". The Redux store has the only actual copy of that data, and your `mapState/useSelector` functions typically return the actual references to that same data. The only copies made are if you make them yourself. Also, the value in the store _is_ already updated before any of the UI subscribers are notified.
Can you put together a sandbox that reproduces this problem and file an issue? I'm very curious what you're actually seeing.
Pretty easy - component that stores a redux computed value and a setTimeout that calls an action with the value. If the settimeout (or a websocket event, etc) fires before the batched update, you are out of sync.
Most people have simple applications so redux works fine, but once you get complicated async work things just break down.
tbh that doesn't sound like a Redux-specific problem. That sounds like a general async / stale-references problem. If you've captured a value and try to use it later, then yeah, you're probably going not going to be using the latest version.
I like redux but what could be achieved with an a tag and another HTML page now needs 700 lines of code due too react, redux, webpack, router, server rendering, partial loading................................................. Yeah I don't want to make my life harder for no reason
I've used redux many times and the amount of boilerplate code is large. What Redux does is cool, but it complicates the app and is a pain to update. I feel this is going to go the way of Java Enterprise Beans as React continues to mature.
As I noted at the start of the post, I updated it literally yesterday with some additional information and links and then tweeted about it, which is why someone else apparently decided to submit it today.
> Is Redux dead, dying, deprecated, or about to be replaced?
No.
Reading through the comments it sounds like it's struggling, even positing the question sews doubt. I thought redux was still one of the 'must have' tools for building react apps now.
What has everyone been migrating to? Is there a consensus successor to Redux?
It depends on your use case, but he mentions some alternative solutions in the article.
1) React's Context API
It's straightforward to use, and it solves the issue of passing data to deeply nested components, but that's all it does.
2) GraphQL Apollo Client
I used this on a recent project for managing client-side state, and to me, it felt like I had to do a lot of work to achieve what should be basic functionality. It was my first foray with Apollo Client, so take my opinion with a grain of salt, but I found myself wishing I was using Redux instead for the duration of the project. Also, Apollo Client has some bugs related to cache invalidation (look on Github). These may be solved now, but they bit me pretty hard.
You can see that net Redux usage overall has continued to increase, and is holding fairly steady at about 50% of React downloads.
Second, for Redux Toolkit specifically, the growth rate from just before we released `[email protected]`, then renamed it to `@reduxjs/[email protected]`, through today:
I updated the post yesterday with new links and information, and tweeted a mention of having done that. Apparently someone thought it was worth submitting.
(tbh I'd forgotten it actually hit the front of HN when I wrote it the first time!)
I really think it should die, from a DDD perspective EDA should be handled as backend tasks with CQRS. If your api server isn't handling that then you really should stand up a BFF. I get that Redux is designed to handle all of that on the front end but it just doesn't belong there. I have seen too many projects devolve into garbage because they are trying to shoehorn too much crap into reducer patterns when it just doesn't belong there.
1. Note that most of the time the stakeholder is yourself and/or another developer. But can also definitely be a non-coder.