A middleware in Redux is defined by the signature
const middleware = store => next => action => {}
What is the definition of action and how are they supposed to be created?
I wanted to create a new middleware for handling async actions, where actions could contain instructions for the side effect to exectute and also the action to dispatch on success. I set up my middleware as follows:
const effectMiddleware = store => next => async (action) => {
// Assert it's actually a command
if (action.command !== undefined) {
next(action)
const result = await Cmd.execute(action.command) // returns a redux action
return store.dispatch(result)
else {
next(action)
}
}
However, I was running into strange errors where the next action would not be executed. I discovered that in fact middleware "actions" are not the same action as the ones you define in your application. Using console log I discovered that action in middlewares is actually
action: Object { type: "MY_ACTION", payload: {} }
stack: undefined
timestamp: 1571214156244
type: "PERFORM_ACTION"
Hence why it did not execute the action returned by Cmd.execute. I managed to get around this by creating a wrapAction function:
const wrapAction = (action) =>
({ action: action, type: "PERFORM_ACTION", stack: undefined, timestamp: new Date().valueOf() })
const effectMiddleware = store => next => async (action) => {
// Assert it's actually a command
if (action.action.command !== undefined) {
next(action)
const result = await Cmd.execute(action.action.command) // Cmd.execute returns a Promise<redux action>
return store.dispatch(wrapAction(result))
else {
next(action)
}
}
However, I can not find the documentation for this anywhere and so my question is: how is the middleware actually meant to be used? What's the official way to "wrap" actions into these middleware actions?
The reason this happens is because of redux devtools! When you use multiple middlewares redux devtools always needs to be last.