0.0.2 • Published 9 years ago
@spalger/redux-async-actions v0.0.2
@spalger/redux-async-actions
A simple wrapper around async redux actions.
Install:
npm install --save @spalger/async-redux-actions
Setup:
Start off by writing some async actions; FSAs with a Promise
as their payload. Then add some asyncHandlers
, which combined with handleActions
(from redux-actions
) and combineReducers
(from redux
) will make up your reducer. Finally tie it all together with with the asyncActionsMiddleware
when you create your store.
actions.js
import { users } from './api'
export const LOAD_USER = 'LOAD_USER'
export function loadUser(id) {
return {
type: LOAD_USER,
payload: users.load(id),
}
}
reducer.js
import { combineReducers } from 'redux'
import { handleActions } from 'redux-actions'
import { asyncHandlers } from '../'
import { LOAD_USER } from './actions'
export default combineReducers({
user: handleActions(asyncHandlers(LOAD_USER), {}),
})
store.js
import { createStore, applyMiddleware } from 'redux'
import { middleware as asyncActionsMiddleware } from '../'
import reducer from './reducer'
const initialState = {}
const enhancer = applyMiddleware(asyncActionsMiddleware)
export default createStore(reducer, initialState, enhancer)
When dispatched, the payload of the LOAD_USER
action will cause the following actions to dispatch, and cause the following state updates:
step | action | state |
---|---|---|
1 | { type: '@@async/START/LOAD_USER' } | { user: { ready: false} } |
2a | { type: '@@async/SUCCESS/LOAD_USER' } | { user: { ready: true, result: User } } |
2b | { type: '@@async/FAILURE/LOAD_USER' } | { user: { ready: true, error } } |
To modify the resulting states you can supply handlers to handleActions(ACTION, handlers)
:
const reducers = combineReducers({
user: handleActions(asyncHandlers(LOAD_USER, {
start: () => ({ fetching: true }),
success: (state, payload) => ({ user: payload }),
error: (state, payload) => ({ reason: payload })
}, {}))
})
// states produced:
// on start: { user: { ready: false, fetching: true } }
// on success: { user: { ready: true, user: User } }
// on failure: { user: { ready: true, reason: error } }
You can simplify the handlers by just supplying a function, which will simply be used for the success handler:
const reducers = combineReducers({
user: handleActions(asyncHandlers(LOAD_USER, (state, payload) => ({ user: payload })), {})
})
// states produced:
// on start: { user: { ready: false } }
// on success: { user: { ready: true, user: User } }
// on failure: { user: { ready: true, error: error } }