Allows you use async functions for payloads in redux. Also supports Promises and synchronous code.
store.dispatch({
type: 'fetchResults',
async payload(dispatch) {
const results = await someApiCall()
dispatch({
type: 'recordResults',
payload: results,
})
},
})
This will dispatch 3 actions, in this order:
[
{
"type": "fetchResults/start"
},
{
"type": "recordResults",
"payload": ["results of your api call"]
},
{
"type": "fetchResults/success"
}
]
npm install --save-dev redux-async-payload
import { applyMiddleware, createStore } from 'redux'
import reduxAsyncPayload from 'redux-async-payload'
const configureStore = applyMiddleware(reduxAsyncPayload({}))(createStore)
// Options are
interface MiddlewareOptions {
delimiter?: string
suffixes?: {
start?: string
success?: string
error?: string
}
}
The payload can be a Promise. This will also dispatch the /start
and
/success
actions:
dispatch({
type: 'fetchResults',
payload: someApiCall(),
})
No matter what you initially pass as a payload, the /success
action will receive the result of it should you want to do anything with it in a reducer or at the point of dispatching:
dispatch({ payload: Promise.resolve(42), type: 'fetchResults' })
// { payload: 42, type: 'fetchResults/success }
dispatch({
async payload() {
return 42
},
type: 'fetchResults',
})
// { payload: 42, type: 'fetchResults/success }
dispatch({
payload() {
return 42
},
type: 'fetchResults',
})
// { payload: 42, type: 'fetchResults/success }
These actions are dispatched by the middleware when the payload is either a Function or a Promise. You can skip them by adding metadata to your action. This acts more like redux-thunk without having to install both middleware:
store.dispatch({
type: 'foo',
payload(dispatch) {
dispatch(/* */)
},
meta: {
asyncPayload: {
skipOuter: true,
},
},
})
dispatch()
now returns Promise<any>
. That means that you can await
it
when dispatching your actions throughout your code, enabling more ways of
combining async actions.
redux-async-payload
comes with ActionStartType
, ActionSuccessType
, and ActionErrorType
.
function reducer(state = initialState, action: AnyAction) {
switch (action.type) {
case startActionType(actions.constants.myAction): {
action = action as ActionStartType<typeof actions.myAction>
return {
...state,
}
}
case successActionType(actions.constants.myAction): {
action = action as ActionSuccessType<typeof actions.myAction>
return {
...state,
}
}
case errorActionType(actions.constants.myAction):
{
action = action as ActionErrorType<typeof actions.myAction>
return {
...state,
}
}
return state
}
}