The code following is the dispatchFunction in store:
self.dispatchFunction = middleware
.reversed()
.reduce({ [unowned self] action in
self._defaultDispatch(action: action)
}) { dispatchFunction, middleware in
// If the store get's deinitialized before the middleware is complete; drop
// the action without dispatching.
let dispatch: (Action) -> Void = { [weak self] in self?.dispatch($0) }
let getState = { [weak self] in self?.state }
return middleware(dispatch, getState)(dispatchFunction)
}
the dispatch function in the code:
let dispatch: (Action) -> Void = { [weak self] in self?.dispatch($0) }
called the dispatchFunction recuusively:
open func dispatch(_ action: Action) {
dispatchFunction(action)
}
So if in the middleware, I called the dispatch function, it will run a endless cycle.
In the CounterExample, I add a middleware:
let loggingMiddleware: Middleware<Any> = { dispatch, getState in
return { next in
return { action in
// perform middleware logic
print(action)
dispatch(action)
// call next middleware
return next(action)
}
}
}
It will lead to a endless loop.

So what the purpose of set a dispatch function parameter in middleware?
With a middleware you can perform some logic that allows you to avoid the given action reach the reducer in some conditions, or to dispatch the same action again if that makes sense, or to dispatch another action as a side effect. For instance, I have a middleware that understands actions coming from my API code; if the middleware gets an action with an API error and this is a 401, I dispatch a logout action from within.
Reading this book I learnt a lot about the whole Redux ecosystem, but overall I understood better what is the purpose of the middleware layer - it turns out it's more powerful and important that I thought it was.
@danielmartinprieto Thank you.
I read some material about middleware here: http://redux.js.org/docs/advanced/Middleware.html
The middleware function here is:
const logger = store => next => action => {
It's input parameter is store.
It is better understood.
While the parameter in middleware of ReSwift is a dispatchFunction and state.
The api error example, why not handle that in reducer? The reducer get a 401 and return a logout action?
Actually, that store you mention from redux.js is { dispatch, getState }, so it's exactly the same we get here in ReSwift!
About my API error example, you can do it in other ways but, in theory, a reducer should only return a new state, not actions. Anyway, that was just an example of dispatching a new action from within a middleware, as a side effect.
Thanks for the explanation, I'll learn those examples.
Thanks for the ebook recommendation, @danielmartinprieto!
@DivineDominion thanks to you for helping develop this library.
I've learnt that with a proper use of middleware, for instance, one doesn't need "async actions" at all. Actually, as a rule of thumb, every entity that performs some kind of IO in your app (an API, a db, a music player...) should be wrapped in its own middleware, and in the rest of the code you will only need plain actions and state changes.
Oh, I didn't really do that much here :)
Interesting approach. I don't know if I like that, but I'll have a look once I read the book :) I go a totally different route in my apps, avoiding both middleware and async action creators. Instead, I write subscribers as services to handle requests. I need to enqueue the request data inside the state and let the service dequeue it, dispatching a completion action etc., which results in more overhead. But so far, I like the separation of a State module and the App module. Then again, middleware could be injected into the store from the App module _instead_ of services.
I see!
When I started using this library I already had worked with redux.js, so I tried to apply what I had learnt. Then I read that book and kept learning from the js community (which has been dealing with Flux and Redux for some time now) and made some changes to my ReSwift usage (mostly making more use of middleware, as I commented before). When the discussion of _action creators_ and _async action creators_ started (see https://github.com/ReSwift/ReSwift/pull/231), I tried to give my input here but it didn't get anywhere, hehe. Now, I don't use _our_ actions creators, because I think the constructors of the actions are that already, and I don't use _async action creators_ either because my middleware handles that - the only pain points I keep having are navigation and animations, but this is something being discussed a lot in the redux.js community, too, so we'll get there.
@danielmartinprieto It's on my list to revisit the action creator APIs.
When I originally built them I seemingly didn't fully understand what their role in Redux is. Insights from folks that come from a Redux background are very welcome!
I'll soon be on paternity leave for a while, If I'm lucky I can carve out a little bit of time to revisit some of the APIs around action creators.
Congratulations!
And looking forward to be part of that revision.
Most helpful comment
Reading this book I learnt a lot about the whole Redux ecosystem, but overall I understood better what is the purpose of the middleware layer - it turns out it's more powerful and important that I thought it was.