redux-act-async

by FredericHeem

FredericHeem /redux-act-async

Reduce boilerplate for redux async actions and reducers

127 Stars 21 Forks Last release: over 3 years ago (v1.5.0) Apache License 2.0 107 Commits 29 Releases

Available items

No Items, yet!

The developer of this repository has not created any items for sale yet. Need a bug fixed? Help with integration? A different license? Create a request here:

redux-act-async

Create async actions and reducers based on redux-act

Install

npm install redux-act-async --save

Badges

Build Status

codecov

npm version

Usage

import thunk from 'redux-thunk'
import {createStore, applyMiddleware} from 'redux';
import {createActionAsync, createReducerAsync} from 'redux-act-async';

// The async api to call, must be a function that returns a promise let user = {id: 8}; function apiOk(){ return Promise.resolve(user); }

// createActionAsync will create 4 synchronous action creators: // login.request, login.ok, login.error and login.reset const login = createActionAsync('LOGIN', apiOk);

/* createReducerAsync takes an async action created by createActionAsync. It reduces the following state given the four actions: request, ok, error and reset. const defaultsState = { loading: false, request: null, data: null, error: null };

if you need to overwrite the defaultsState just insert your initialState as a second paramenter in the createReducerAsync function. Just like that:

const initialState = { loading: false, request: null, data: {custom: "intitial data"}, error: null };

const reducer = createReducerAsync(login, initialState)

*/ const reducer = createReducerAsync(login)

const store = createStore(reducer, applyMiddleware(thunk));

await store.dispatch(login({username:'lolo', password: 'password'}));

Legacy redux

In a nutshell, the following code:

const options = {noRethrow: false};
const loginAction = createActionAsync('LOGIN', api, options);
const loginReducer = createReducerAsync(loginAction)

is equivalent to:

const LOGIN_REQUEST = 'LOGIN_REQUEST'
const LOGIN_OK = 'LOGIN_OK'
const LOGIN_ERROR = 'LOGIN_ERROR'
const LOGIN_RESET = 'LOGIN_RESET'

const loginRequest = (value) => ({ type: LOGIN_REQUEST, payload: value })

const loginOk = (value) => ({ type: LOGIN_OK, payload: value })

const loginError = (value) => ({ type: LOGIN_ERROR, payload: value })

const loginReset = (value) => ({ type: LOGIN_RESET, payload: value })

const options = {noRethrow: true};

export const login = (...args) => { return (dispatch, getState) => { dispatch(loginRequest(...args)); return api(...args, dispatch, getState) .then(response => { const out = { request: args, response: response }

  dispatch(loginOk(out))
  return out;
})
.catch(error => {
  const errorOut = {
      actionAsync,
      request: args,
      error: error
  }
  dispatch(loginError(errorOut))
  if(!options.noRethrow) throw errorOut;
})

} }

const defaultsState = { loading: false, request: null, data: null, error: null };

const reducer = createReducer({ [actionAsync.request]: (state, payload) => ({ ...state, request: payload, loading: true, data: null, error: null }), [actionAsync.ok]: (state, payload) => ({ ...state, loading: false, data: payload.response }), [actionAsync.error]: (state, payload) => ({ ...state, loading: false, error: payload.error }), [actionAsync.reset]: () => (defaultsState) } , defaultsState);

That's 3 lines against 78 lines, a good way to reduce boilerplate code.

Async Action Options

Here are all the options to configure an asynchronous action:

const actionOptions = {
  noRethrow: false,
  request:{
    callback: (dispatch, getState, ...args) => {
    },
    payloadReducer: (payload) => {
      return payload
    },
    metaReducer: (meta) => {
      return ASYNC_META.REQUEST
    }
  },
  ok:{
    callback: (dispatch, getState, ...args) => {
    },
    payloadReducer: (payload) => {
      return payload
    },
    metaReducer: () => {
      return ASYNC_META.OK
    }
  },
  error:{
    callback: (dispatch, getState, ...args) => {
    },
    payloadReducer: (payload) => {
      return payload
    },
    metaReducer: () => {
      return ASYNC_META.ERROR
    }
  }
}

const loginAction = createActionAsync('LOGIN', api, actionOptions);

Who is using this library ?

This library has been extracted originally from starhack.it, a React/Node Full Stack Starter Kit.

We use cookies. If you continue to browse the site, you agree to the use of cookies. For more information on our use of cookies please see our Privacy Policy.