Skip to content

Lightweight, no dependency library for redux reducers

License

Notifications You must be signed in to change notification settings

d1slike/redux-utils

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

28 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

redux-reducer-utils

npm version Build Status Coverage Status

Lightweight, no dependency library for redux reducers

Install

npm install --save redux-reducer-utils

Or

yarn add redux-reducer-utils

Usage

Reducer creation

createReducer provides more declarative way to describe redux reducer

Just call createReducer with initial state as argument and then invoke chain when to register actions handlers, finally call toFunction to build reducer

import {createReducer} from 'redux-reducer-utils';

const initialState = {
    a: 1,
    b: 2,
    c: 3,
    d: 4,
};

const reducer = createReducer(initialState)
    .when(ACTION_TYPE_1, (state, action) => ({
        ...state,
        a: state.a + action.payload,
    }))
    .when(ACTION_TYPE_4, (state, action) => ({
        ...state,
        c: state.c + action.payload,
    }))
    .toFunction();

Here comparison classic reducer description with createReducer way

const ACTION_TYPE_1 = 'ACTION_TYPE_1';
const ACTION_TYPE_2 = 'ACTION_TYPE_2';
const ACTION_TYPE_3 = 'ACTION_TYPE_3';
const ACTION_TYPE_4 = 'ACTION_TYPE_4';

const initialState = {
    a: 1,
    b: 2,
    c: 3,
    d: 4,
};

const classicReducer = (state = initialState, action) => {
    switch (action.type) {
        case ACTION_TYPE_1:
            return {
                ...state,
                a: state.a + action.payload,
            };
        case ACTION_TYPE_2:
        case ACTION_TYPE_3:
            return {
                ...state,
                b: state.b + action.payload,
            };
        case ACTION_TYPE_4:
            return {
                ...state,
                c: state.c + action.payload,
            };
        default:
            return state;
    }
};

const withCreateReducer = createReducer(initialState)
    .when(ACTION_TYPE_1, (state, action) => ({
        ...state,
        a: state.a + action.payload,
    })) //if you need the same handler for two or more actions types, just put array to first argument
    .when([ACTION_TYPE_2, ACTION_TYPE_3], (state, action) => ({
        ...state,
        b: state.b + action.payload,
    }))
    .when(ACTION_TYPE_4, (state, action) => ({
        ...state,
        c: state.c + action.payload,
    }))
    .toFunction();

Reducer composition

composeReducers This function can help with reducers horizontal scaling

Every i reducer has access to i-1 state

import {composeReducers} from 'redux-reducer-utils';

const SOME_ACTION = 'SOME_ACTION';

const initialStateFirst = {
    a: 1,
    b: 2,
};

const initialStateSecond = {
    c: 3,
    d: 3,
};

const firstReducer = (state = initialStateFirst, action) => {
    //...some actions handlers
};

const secondReducer = (state = initialStateSecond, action) => {
    //...here you have access to state from firstReducer
    switch (action.type) {
        case SOME_ACTION:
            return {
                ...state,
                a: state.a + action.payload,
            };
        default:
            return state;
    }
};

export const composedReducer = composeReducers(firstReducer, secondReducer, /*...any number of reducers*/);