In addition, if you want to have your app load as smaller chunks rather than a single large bundle, you need to be careful to ensure that things work even all the backing reducers aren't yet loaded.
In addition, if you want to have your app load as smaller chunks rather than a single large bundle, you need to be careful to ensure that things work even all the backing reducers aren't yet loaded.
I need to update a remote resource. But wait! Sometimes that can fail. I need to capture the failure logic and make appropriate ui changes. There are 4 types of errors and they require doing some library logic to figure out what to display.
But wait! I want to wait 250ms before triggering any state updates, or else the ui transitions will feel buggy.
Oh, and product now wants to make sure we capture some random third party tracking event in between specific state changes. The ui MUST NOT change until the tracking call succeeds.
This and more is trivial in redux saga, and you can write tests around it.
Today, our recommendations are:
- Data fetching: default to using RTK Query, fall back to thunks if needed
- Responding to actions or state changes: use the new RTK "listener" middleware as the main approach
See my recent talk "The Evolution of Redux Async Logic" for details:
- https://blog.isquaredsoftware.com/2022/05/presentations-evol...
as well as my recent presentation going through "Modern Redux with Redux Toolkit":
- https://blog.isquaredsoftware.com/2022/06/presentations-mode...
And now there are multiple deployed production apps with real users, so it’s almost certainly never going to be replaced. The cost would be enormous.
But as I put it in my "Evolution" talk: "Sagas are like a chainsaw. Really powerful, and really dangerous. If you actually _need_ that power, great! But most of the time you don't actually _need_ to use a chainsaw on a daily basis."
As the sibling comment said, a lot of times sagas really do end up as spaghetti code, largely because they are so event-driven, and with all the use of generator functions that can make debugging hard. (Ironically, the original Flux Architecture was created to _avoid_ the problems of Backbone-style event triggers causing events to ricochet around the app without a way to understand how things would update in response, and sagas can end up recreating that problem with Redux apps.)
You can do all of that pretty easily with a vanilla redux.
> In addition, if you want to have your app load as smaller chunks rather than a single large bundle, you need to be careful to ensure that things work even all the backing reducers aren't yet loaded.
In the decade old application we use redux saga in at work, a large portion of our 7MB minified/gzipped main chunk is redux handlers. It'd be nice if there was a relatively simple way to not synchronously load all the reducers up front.
- https://redux.js.org/usage/code-splitting
There have been some different community packages for helping with that process, but some of them seem to have become outdated (only worked with React-Redux v5, etc). I did see a new one at https://github.com/fostyfost/redux-eggs that seemed like it had potential, but I haven't had a chance to try any of them myself.
I also once saw someone play around with the idea of using React's still-not-technically-final Suspense support to help ensure that a lazy-loaded component that relies on a code-split reducer doesn't actually get rendered until that reducer's state is available. Don't have the link handy atm, but if someone wants it ping me and I can go figure out where that was described.
Also, the new RTK "listener" middleware was specifically designed to replace almost all saga usages, and you can dynamically add more listeners at runtime via dispatch an `addListener()` action:
- https://redux-toolkit.js.org/api/createListenerMiddleware
- https://blog.isquaredsoftware.com/2022/05/presentations-evol...