Splitting and combining reducers

As your application grows, you probably wouldn't want to write all the logic for how the state of your application needs to be transformed in a simple reducer function. What you would probably want is to write smaller reducers that specialize in managing independent parts of the state.

Take for example the following reducer function:

const initialState = { 
    todoList: [], 
    chatMsg: [], 
} 
const reducer = (state = initialState, action) => { 
    switch (action.type) { 
        case 'ADD_TODO': return { 
            ...state, 
            todoList: [ 
                ...state.todoList, 
                { 
                    title: action.title, 
                    completed: action.completed, 
                }, 
            ], 
        } 
        case 'ADD_CHAT_MSG': return { 
            ...state, 
            chatMsg: [ 
                ...state.chatMsg, 
                { 
                    from: action.id, 
                    message: action.message, 
                }, 
            ], 
        } 
        default: 
            return state 
    } 
} 

You have two properties that manage the state of two different parts of an application. One manages the state of a Todo, list while the other manages the Chat messages. You could split this reducer into two reducer functions, where each manages one slice of the state, for instance:

const initialState = { 
    todoList: [], 
    chatMsg: [], 
} 
const todoListReducer = (state = initialState.todoList, action) => { 
    switch (action.type) { 
        case 'ADD_TODO': return state.concat([ 
            { 
                title: action.title, 
                completed: action.completed, 
            }, 
        ]) 
        default: return state 
    } 
} 
const chatMsgReducer = (state = initialState.chatMsg, action) => { 
    switch (action.type) { 
        case 'ADD_CHAT_MSG': return state.concat([ 
            { 
                from: action.id, 
                message: action.message, 
            }, 
        ]) 
        default: return state 
    } 
} 

However, because createStore method accepts only one reducer as the first argument, you would need to combine them into a single reducer:

const reducer = (state = initialState, action) => { 
    return { 
        todoList: todoListReducer(state.todoList, action), 
        chatMsg: chatMsgReducer(state.chatMsg, action), 
    } 
} 

In this way, we are able to split our reducers into smaller reducers that specialize in managing only one slice of the state, and later combine them together into a single reducer function.

Redux provides a helper method named combineReducers that allows you to combine reducers in a similar way to what we just did but without having to repeat a lot of code; for instance, we could rewrite the previous way of combining reducers like this:

const reducer = combineReducers({ 
    todoList: todoListReducer, 
    chatMsg: chatMsgReducer, 
}) 

The combineReducers method is a higher-order reducer function. It accepts an object mapping specifies keys to a certain slice of the state managed by a specific reducer function and returns a new reducer function. If you run the following code, for instance:

console.log(JSON.stringify( 
    reducer(initialState, { type: null }), 
    null, 2, 
)) 

You will see that the generated shape of the state looks like this:

{ 
    "todoList": [], 
    "chatMsg": [], 
} 

We can try as well if our combined reducers are working and managing only the part of the state assigned to them. For instance:

console.log(JSON.stringify( 
    reducer( 
        initialState, 
        { 
            type: 'ADD_TODO', 
            title: 'This is an example', 
            completed: false, 
        }, 
    ), 
    null, 2, 
)) 

The output should display the generated state as the following:

{ 
    "todoList": [ 
        { 
            "title": "This is an example", 
            "completed": false, 
        }, 
    ], 
    "chatMsg": [], 
} 

This shows that each reducer is managing only the slice of the state assigned to them.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.218.25.67