Skip to content

brechtbilliet/create-reducer-tree

Repository files navigation

Create-reducer-tree

This library is created to help you with creating large reducer trees (Hierachical reducer composition). Reducers and reducer-composition are principles from Redux.

Installing

npm install create-reducer-tree

Usage

###Import it

import {createReducerTree} from "create-reducer-tree";

###Create a reducerComposer object You will have to create an object that looks like the object shown below. It's actually a hierachical object that represents the store. At the deepest level you have to define actions and one reducer. Normally you would have to write parentreducers that delegate to childreducers based on certain actions. These parentreducers will determine which references are renewed in the immutable state tree. createReducerTree will create that boilerplatecode for you.

let reducerComposer: any = {
    groceryManagement: {
        data: {
            groceries: {
                initialState: [],
                actions: ["ACTION1", "ACTION2"],
                reducer: groceriesReducer
            }
        },
        container: {
            currentList: {
                initialState: null,
                actions: ["ACTION3", "ACTION4"],
                reducer: currentListReducer
            }
        }
    },
    listManagement: {
        data: {
            lists: {
                initialState: [],
                actions: ["ACTION5"],
                reducer: listsReducer
            }
        },
        container: {
            groceryListsEdit: {
                initialState: {list: null},
                actions: ["ACTION6"],
                reducer: groceryListsEditReducer
            }
        }
    },
    common: {
        container: {
            application: {
                initialState: {isBusy: false},
                actions: ["ACTION7"],
                reducer: applicationReducer
            },
            collapsableSidebar: {
                initialState: {isCollapsed: false},
                actions: ["ACTION8"],
                reducer: collapsableSidebarReducer
            }
        }
    }
};

// generate a store with the boilerplate reducers based on actions and initialstate
let store = createReducerTree(reducerComposer);

Problem explained: scenario

Let's say the store receives ACTION1 or ACTION2. This will result in groceriesReducer to have been called and new references created for:

  • groceryManagement
  • groceryManagement > data
  • groceryManagement > data > groceries
  • listManagement (but nothing below)
  • common (but nothing below)
The pieces of state that should **not** have new references are
  • groceryManagement > container and everything below
  • listManagement > data and everything below
  • listManagement > container and everything below
  • common > container and everything below

To get this behavior (and make sure that not the entire tree gets new references) you had to manually create reducers for all hierachical levels. Normally you would have to write boilerplate code for all these reducers.

  • groceryManagementReducer
  • groceryManagementDataReducer
  • groceryManagementContainerReducer
  • listManagementReducer
  • listManagementDataReducer
  • listManagementContainerReducer
  • commonReducer
  • commonContainerReducer
  • commonCollapsableSidebarReducer
Writing the reducers above can take a lot of time to write/unittest/maintain.

This is an example of a reducer that we had to write before to optimize the tree.

export function groceryManagementReducer(state: GroceryManagementState = {data:{...}}, action: Action): GroceryManagementState {
    switch (action.type) {
        case "ACTION1":
        case "ACTION2":
            return {
                data: dataReducer(state.data, action),
                container: containerReducer(state.container, action)
            }
    }
    return state;
}

All these reducers are generated for you by create-reducer-tree

About

Simple script to help with large reducer hierarchies

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published