@spalger/redux-async-actions

0.0.2 • Public • Published

@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 } }

Package Sidebar

Install

npm i @spalger/redux-async-actions

Weekly Downloads

2

Version

0.0.2

License

MIT

Last publish

Collaborators

  • spalger