Live data from Hacker News

JavaScript Power Tools: Real-World Redux-Saga Patterns

formidable.com

31–40 of 47 posts

Re: JavaScript Power Tools: Real-World Redux-Saga Patterns

#31
post #19
post #16

I don't understand. Why not simply observables?

Author here. Saying "why not simply observables" kinda glosses over a lot of details, but I'll try and answer as best as I can. I've always found it a bit difficult to use Observables in application-style code, both in a conceptual sense (handling Redux actions as an observable stream) and in a practical sense (actually building and debugging streams and transformations over those streams). I do think they're excelle…

Yes, this article assumes (rightfully) that people are using redux saga and need help with it.

I just found the whole concept of redux and redux-saga a bit strange. It seemed like people don't want to use observables for whatever reasons and try to push Redux to solve these async problems.

Your article is good, I just had the feeling it wouldn't be needed if people would use better suited abstractions in the first place.

Re: JavaScript Power Tools: Real-World Redux-Saga Patterns

#32
post #30

Earlier quoted context omitted.

Well, one of the primary design goals behind Redux was to make async behavior a pluggable approach (as detailed in my blog post "The Tao of Redux, Part 1 - Implementation and Intent" [0]). So, I don't see how use of redux-saga, or redux-thunk, or any other async middleware, qualifies as "bending Redux until it does their bidding", given that it was explicitly intended to allow that. On the other hand, there definitel…

I used Redux back in the days and async behavior felt rather clunky (action begin, action success, actionFailure) the other approaches felt like somehow getting rid of this clunky stuff. Using observables instead of Redux doesn't even lead to these fixes.

As I describe in that "Tao of Redux Part 2" post, there's no _requirement_ that you dispatch START/SUCCESS/FAILURE actions as part of your async requests. You'd need SUCCESS at a minimum or an equivalent to handle the actual updates from the request, but the START/FAILURE actions are only needed if you want want to do things like showing spinners or have some kind of undo/redo behavior. It's a useful convention and a common pattern, but definitely not a requirement.

Re: JavaScript Power Tools: Real-World Redux-Saga Patterns

#33
post #25

Earlier quoted context omitted.

Interesting. What specific concerns or pain points did you experience? Any examples of "reasoning about what code runs next is easy, until it's not" ?

The put/call/takeLatest/takeEvery effects, coupled with all the yields made things impossible to grok for the less seasoned folks. Even for me, having seen some similar things before with other libraries in other languages, it's just not a pattern that my brain wraps itself easily around. There is so much indirection between the sagas and reducers and the effects. Like, I just want to see the code that actually does…

My gripe about sagas is that it mostly reimplement observables-like APIs on top of generators. Observables do take a bit to learn, but once you learnt them, the knowledge is more or less reusable across platforms (even if it's a little different, you can do Go, Scala/Akka, Elixir, and any language that has an Rx implementation).

With Sagas, while the upfront cost and the gain are in the same ballpark for Redux apps, that's basically the only place you'll use the investment. You also cannot leverage the collective knowledge and patterns of the tens of thousands of engineers from other platforms.

That makes it a lot less palatable to me, even though they are easier on the eyes at first, especially for people with mostly procedural programming backgrounds (which is the more common case).

Unlike the initial statement, I do think they're easier to test than even Observables/Promises, because generators make it so easy to inject results and dependencies anywhere in a complex flow. But marble tests aren't bad either.

Re: JavaScript Power Tools: Real-World Redux-Saga Patterns

#34
post #31
post #19

Earlier quoted context omitted.

Author here. Saying "why not simply observables" kinda glosses over a lot of details, but I'll try and answer as best as I can. I've always found it a bit difficult to use Observables in application-style code, both in a conceptual sense (handling Redux actions as an observable stream) and in a practical sense (actually building and debugging streams and transformations over those streams). I do think they're excelle…

Yes, this article assumes (rightfully) that people are using redux saga and need help with it. I just found the whole concept of redux and redux-saga a bit strange. It seemed like people don't want to use observables for whatever reasons and try to push Redux to solve these async problems. Your article is good, I just had the feeling it wouldn't be needed if people would use better suited abstractions in the first pl…

I'm still not sure exactly what you're trying to say there, particularly by "push Redux to solve these async problems".

Redux itself is about synchronous state updates, as inspired by the Flux Architecture. Because of that, async behavior and side effects are handled via middleware.

Most developers are not overly comfortable with FP concepts or code. Redux was intended as a lightweight intro to FP principles, and React also helps push people in that direction. Even fewer people are comfortable with observables, although Angular is maybe starting to change that somewhat. So, it's not just about "better suited abstractions", it's about what developers understand and can use well.

To be honest, your comments seem to be leaning towards the common stereotype of an FP enthusiast: "This approach is clearly superior and correct, why would people do anything else?"

Re: JavaScript Power Tools: Real-World Redux-Saga Patterns

#36
post #22

I worked on a fairly large and high traffic React app. It had some complicated async flows, so the team moved from redux-thunk to sagas. The claims that testability is improved do not ring true to me. Some of those tests were just awful to write and maintain. I'm sure someone will say "you were doing it wrong" but there were many folks on the team following advice from the maintainers themselves on Discord. General u…

Any claims about scalability or testability mean nothing without concrete code examples to back them up. Any tool that makes claims such as these without a sufficiently complex example in the docs, alongside a baseline implementation for comparison, is a huge red flag IMO.

Re: JavaScript Power Tools: Real-World Redux-Saga Patterns

#37
post #35

A whole class of problems you wouldn't have in the first place with MobX. So much code in the article for doing so little - where good design could solve the issues much more elegantly using plain function composition and JS concepts.

Author here.

As I mentioned in other posts, I don't believe redux-saga is the be-all-end-all solution to every problem in client-side Javascript. It's a good solution for codebases which need to coordinate among several different asynchronous processes.

And for what it's worth, I wanted to err on the side of verbosity. I find that a lot of blog posts kinda elide over too much, and so I was actively trying to break down my thought process into very discrete steps. At the end of the day, I think you'll find that the final product involves less than 300 lines of code. If that.

On a different tack, MobX is an excellent library, and we've actually used it to great effect at Formidable! Ken Wheeler has a great post about the topic. The point of this article, though, is simply to share something that worked well for us on a complex project, where replacing Redux with MobX wouldn't have been that helpful.

Along those lines, I ask you in complete honesty: what would you like to see out of a "Javascript Power Tools: MobX" article? I'd love to dig into it a little bit, find out what makes it tick, and share that with folks. :)

Re: JavaScript Power Tools: Real-World Redux-Saga Patterns

#38
post #31

Earlier quoted context omitted.

Yes, this article assumes (rightfully) that people are using redux saga and need help with it. I just found the whole concept of redux and redux-saga a bit strange. It seemed like people don't want to use observables for whatever reasons and try to push Redux to solve these async problems. Your article is good, I just had the feeling it wouldn't be needed if people would use better suited abstractions in the first pl…

I'm still not sure exactly what you're trying to say there, particularly by "push Redux to solve these async problems". Redux itself is about synchronous state updates, as inspired by the Flux Architecture. Because of that, async behavior and side effects are handled via middleware. Most developers are not overly comfortable with FP concepts or code. Redux was intended as a lightweight intro to FP principles, and Rea…

> Because of that, async behavior and side effects are handled via middleware.

It shouldn't be though. The middleware pattern makes a lot of sense for transforming data (communication between mismatched APIs etc), or using it in some way before passing it on (logging, analytics etc). IMO it's totally wrong for this use case though.

All redux-thunk is doing is taking some "action", clobbering it, pretending it doesn't exist, and running some arbitrary function that it's passed.

dispatch(higherOrderFunctionThatCreatesAsyncFunction())

is identical to

asyncFunction()

What people are looking for is some way to get the data store dependencies into asyncFunction in a testable way. This can easily be done without middleware.

Re: JavaScript Power Tools: Real-World Redux-Saga Patterns

#39
post #38

Earlier quoted context omitted.

I'm still not sure exactly what you're trying to say there, particularly by "push Redux to solve these async problems". Redux itself is about synchronous state updates, as inspired by the Flux Architecture. Because of that, async behavior and side effects are handled via middleware. Most developers are not overly comfortable with FP concepts or code. Redux was intended as a lightweight intro to FP principles, and Rea…

> Because of that, async behavior and side effects are handled via middleware. It shouldn't be though. The middleware pattern makes a lot of sense for transforming data (communication between mismatched APIs etc), or using it in some way before passing it on (logging, analytics etc). IMO it's totally wrong for this use case though. All redux-thunk is doing is taking some "action", clobbering it, pretending it doesn't…

Yes, yes, we've had this argument about redux-thunk in prior threads :)

That said, it's worth noting that the explicit design goal for middleware _was_ for async behavior, per the comments from Dan and Andrew I've quoted in http://blog.isquaredsoftware.com/2017/05/idiomatic-redux-tao... . To pick out one specific quote from 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." My previous Flux library, Flummox, had what was essentially a promise middleware built in. It was convenient for some, but because it was built in, you couldn't change or opt-out of its behavior. 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.

> Redux Thunk is promoted in the docs because it's the absolute bare minimum solution. We were confident that the community would come up with something different and/or better. We were right!

Re: JavaScript Power Tools: Real-World Redux-Saga Patterns

#40
post #35

A whole class of problems you wouldn't have in the first place with MobX. So much code in the article for doing so little - where good design could solve the issues much more elegantly using plain function composition and JS concepts.

Agreed. Just refactored a medium sized redux/redux-saga codebase (20 kloc) to MobX. Shaved off a couple of thousand loc of logic and boilerplate in the process, and everything became so much easier to reason about.
Post reply on HN