DEV Community

[Comment from a deleted post]
 
ben profile image
Ben Halpern

Thanks for the comment Mark. Your response has me pretty motivated to think a lot harder about why I feel the way I do. I'll read through that discussion and definitely ping you about it at some point.

 
markerikson profile image
Mark Erikson

Great, looking forward to hearing your feedback!

I will freely tell people that Redux isn't for everyone, and it isn't for all situations. However, I do think that a lot of people misunderstand the reasons why Redux works the way it does.

For anyone interested in that topic, I suggest reading these articles:

 
kspeakman profile image
Kasey Speakman • Edited

The biggest omission in Redux is a declarative way to represent external side effects like API calls. It was such a felt absence that a lot of libraries have sprung up to handle this. And each middleware has its own set of tradeoffs to weigh.

If Redux reducers could return declarative side effects along with the store changes, and if the side effects could trigger messages back into Redux to report the outcome, that would complete the external feedback loop. And a lot of middleware confusion would be avoided. The same kind of pattern can be used for local side effects as well (e.g. FileReader API). That's the model used by Elm, although the pattern is older than that.

 
markerikson profile image
Mark Erikson

Redux was deliberately designed to leave side effects as an external consideration so that users could choose their preferred syntax. See the slides from my recent presentation on the Redux ecosystem for some quotes from Dan and Andrew on that topic.

One of the slides in that presentation shows stats on the most popular Redux side effects libraries. redux-thunk and redux-saga are by far the most popular, indicating that Redux users prefer to deal with plain functions and generator functions. redux-observable has interest, but is less popular.

If you do want declarative side effects returned from reducers, then the redux-loop library is for you. There's also several other libraries for reducer-based side effects as well.

But no, I wouldn't call this situation an "omission". It was a deliberate decision to let the community decide what side effects approaches they want to use with Redux.

 
kspeakman profile image
Kasey Speakman

I don't really buy that it was a deliberate decision, based on this issue for one. I think it's more probable that the reason was just not knowing how to implement it robustly. (And I would not have known either! Not judging!) But I do take your point.

In any case, I was just expressing my feedback. Side effects (especially API calls) are table stakes for almost everything I develop. So this absence and instead adding 5 more things (side effect libraries) to my list of things to evaluate before starting my first Redux project was a hindrance. So much so that I never did. But I would love to see Redux usage and FP grow further among React users. I think it benefits us all. So I offered my feedback, such as it is. Thanks for your time and best wishes!

 
markerikson profile image
Mark Erikson

Note that there's a distinct difference between "not being sure how to go about implementing reducer-based side effects", and "deliberately deciding to not have side effect management as part of the Redux core". Two specific quotes from Dan and Andrew's AMA on Hashnode show that it was a deliberate decision:

  • Andrew: "The reason the middleware API exists in the first place is because we explicitly did not want to prescribe a particular solution for async. With Redux, we knew that the community would come up with a multitude of better async solutions that whatever we could have built in ourselves."
  • Dan: "We didn’t want to prescribe something like this in Redux itself because we know a lot of people are not comfortable with learning Rx operators to do basic async stuff. It’s beneficial when your async logic is complex, but we didn’t really want to force every Redux user to learn Rx, so we intentionally kept middleware more flexible."

So, having side effects approaches not be built into the core was clearly a deliberate design decision.

There's obviously a lot of different ways to manage async behavior in JS. Callbacks, promises, async/await, observables, and much more. You're right that choosing a side effects approach is something Redux users need to do. This is both a strength and a bit of a pain point.

My React/Redux links list has a large section of articles on Redux side effects approaches, including many articles comparing different libraries. My own personal advice is to start with thunks, and if you need a more powerful async approach, using sagas or observables based on your preference for syntax. From your comments, it sounds like redux-loop is more what you're looking for.