From ebd2c3e26a24005d4ab9586850ba231bf2ae3a80 Mon Sep 17 00:00:00 2001 From: Arian Allenson Valdez Date: Sat, 6 Jul 2019 17:28:22 +0800 Subject: [PATCH] Add composeReducers --- README.md | 31 +++++++++++++++++++++++++++++++ __tests__/immer-reducer.test.tsx | 25 +------------------------ src/immer-reducer.ts | 25 +++++++++++++++++++++++++ 3 files changed, 57 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index 033535e..70c8b3e 100644 --- a/README.md +++ b/README.md @@ -323,3 +323,34 @@ Example ```ts setPrefix("MY_APP"); ``` + +### `function composeReducers(...reducers)` + +Utility that reduces actions by applying them through multiple reducers. +This helps in allowing you to split up your reducer logic to multiple `ImmerReducer`s +if they affect the same part of your state + +Example + +```ts +class MyNameReducer extends ImmerReducer { + setFirstName(firstName: string) { + this.draftState.firstName = firstName; + } + + setLastName(lastName: string) { + this.draftState.lastName = lastName; + } +} + +class MyAgeReducer extends ImmerReducer { + setAge(age: number) { + this.draftState.age = 8; + } +} + +export const reducer = composeReducers( + createReducerFunction(MyNameReducer, initialState), + createReducerFunction(MyAgeReducer, initialState) +) +``` diff --git a/__tests__/immer-reducer.test.tsx b/__tests__/immer-reducer.test.tsx index 0ee6e45..2105916 100644 --- a/__tests__/immer-reducer.test.tsx +++ b/__tests__/immer-reducer.test.tsx @@ -2,6 +2,7 @@ import { ImmerReducer, createReducerFunction, createActionCreators, + composeReducers, setPrefix, _clearKnownClasses, isAction, @@ -10,35 +11,11 @@ import { import {createStore, combineReducers, Action} from "redux"; -interface Reducer { - (state: State | undefined, action: any): State; -} - beforeEach(_clearKnownClasses); afterEach(() => { setPrefix("IMMER_REDUCER"); }); -/** - * Combine multiple reducers into a single one - * - * @param reducers two or more reducer - */ -function composeReducers( - ...reducers: (Reducer)[] -): Reducer { - return (state: any, action: any) => { - return ( - reducers.reduce((state, subReducer) => { - if (typeof subReducer === "function") { - return subReducer(state, action); - } - - return state; - }, state) || state - ); - }; -} test("can create reducers", () => { const initialState = {foo: "bar"}; diff --git a/src/immer-reducer.ts b/src/immer-reducer.ts index 0d02343..9270b86 100644 --- a/src/immer-reducer.ts +++ b/src/immer-reducer.ts @@ -142,6 +142,31 @@ export function isActionFrom( return isActionFromClass(action, immerReducerClass); } +interface Reducer { + (state: State | undefined, action: any): State; +} + +/** + * Combine multiple reducers into a single one + * + * @param reducers two or more reducer + */ +export function composeReducers( + ...reducers: (Reducer)[] +): Reducer { + return (state: any, action: any) => { + return ( + reducers.reduce((state, subReducer) => { + if (typeof subReducer === "function") { + return subReducer(state, action); + } + + return state; + }, state) || state + ); + }; +} + /** The actual ImmerReducer class */ export class ImmerReducer { static customName?: string;