> 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.
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.
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!
Yeah I'm under no illusions that me and Dan Abramov are operating under a vastly different model for how we think an application should be structured. The concept of a data store having a "solution for async" is, to me at least, absurd. It's like asking why my fridge doesn't have a solution for next day grocery delivery.
I don't see why my fridge needs to be concerned about whether my broccoli is sitting on the bench ready to be put in, or still being washed down at the green grocers.
From the fridge's point of view, a piece of broccoli is inserted into it at a specific point of time. The contents of the fridge can be defined as an ordered set of insertions and removals. The fridge's state depends on knowing whether a piece of broccoli was inserted at 12:58pm or 1:03pm, since that may change the order things were stacked in, but it doesn't need to know whether I placed an order for that broccoli this morning, yesterday, or a week ago; or how it arrived at my house. Making my fridge responsible for that process would seem to violate the concept of separation of concerns.
Funny thing is that Dan himself said Redux could be implemented in 5 lines of RxJS and was also rathere interested in observables til he met some haters on a conf.
I remember him asking a question about observables being the next thing or future or something and the speaker just didn't know what to say.
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.