@reggev/async-actions
v1.0.1
Published
redux async actions middleware
Downloads
3
Readme
async-action
A Redux middleware to handle asynchronous actions.
The middleware is "activated" by providing types
object
instead of a type
string like you would do in a standard redux action.
The types object contains 3 values: pending, success, and fail. Each is an action type and should be a string.
{
types: {
pending: 'FETCH_SOMETHING_PENDING',
success: 'FETCH_SOMETHING_SUCCESS',
fail: 'FETCH_SOMETHING_FAIL',
}
}
The middleware accepts a few more properties
callApi
Accepts a function that returns a promise, you can use any async library/method you'd like here. example:
{
callApi: () => someHTTPLibrary.get('/my-server')
}
the pending action will be raised -> then the callApi method will be triggerd and the fail/success action will be raised according to the promise callApi retured
optimisticResponse (optional)
You can pass an object to this field for your reducers to optimistically update them This value is added to the pending action.
You can also pass a function to this property, it will receive the entire state so you can produce your optimistic response based on your current state.
you should mock the server's success response as accurately as possible here This way, you can make your app feel faster, and let the slow process happen in the background, useful in trivial cases like toggling switches
{
callApi: () => someHTTPLibrary.patch(`/my-server/${todoId}?done=true`)
optimisticResponse: {
todoId,
isDone: true
}
}
in case the callApi promise failed, the initial state is passed to fail action so that you can restore the state to its original state -> you can also write a store enhancer to do that automatically! if your promise failed and you restore the state it is a good practice to show some notification to your users to let them know the action failed
postProcess (optional)
here you can pass a method that receives the response data and returns a post-processed response before it's passed to the reducer. This method modifies the payload object.
{
postProcess: data => normalizeMyData(data, normalizeSchema)
}
this is a good place for normalizing data or setting local values
you can pass any extra fields to the object, and they will be added to all 3 actions This is in case you need some extra metadata, or you are using other middlewares
The three resulting actions look like this
pending:
{
...extraFields,
type: types.pending,
optimisticResponse (optional)
}
success:
{
...extraFields,
type: types.success,
payload: postProcess ? postProcess(responseData) : responseData
}
fail:
{
...extraFields,
type: types.fail,
payload: responseData,
initialState,
error: true
}