Last article As you can see, the two reducer functions are the current state and the action of this dispatch.
The structure of state is a JavaScript object, and each key can represent data of different meanings. For instance
{ lists:object, type:string }
lists manage list data, and type manages the selected type. At this point, we need to consider dividing state into different subtrees, each subtree data corresponds to a reducer subtree, and manage the corresponding state separately. But the reducer received by the createStore (reducer, preloaded State) function must be a single function. At this point, we need to use the combinReducers function, which is to merge multiple reducer functions into a final reducer function.
combineReducers(reducers)
Take a look at the core code of the combineReducers function implementation. The following code deletes the exception prompt and handling part, leaving only the key part.
export default function combineReducers(reducers) { //value is not function al in filtering parameters const reducerKeys = Object.keys(reducers) const finalReducers = {} for (let i = 0; i < reducerKeys.length; i++) { const key = reducerKeys[i] if (typeof reducers[key] === 'function') { finalReducers[key] = reducers[key] } } // All key values of the processed reducers object const finalReducerKeys = Object.keys(finalReducers) // Returns the merged reducer function, which receives the same parameters as the normal reducer function. // Here the state is the complete data structure, and the single reducer function receives only the subtree it manages. return function combination(state = {}, action) { let hasChanged = false const nextState = {} // When an action assignment occurs, all child reducer s are triggered // Because action has a type field, the corresponding reducer function is triggered. for (let i = 0; i < finalReducerKeys.length; i++) { const key = finalReducerKeys[i] const reducer = finalReducers[key] // Corresponding subtree data const previousStateForKey = state[key] // Call the corresponding reduer function to return the update result of subtree data const nextStateForKey = reducer(previousStateForKey, action) // Subtree data synchronized to state nextState[key] = nextStateForKey // Whether markup data changes, as long as a subtree changes, even if the data has changed hasChanged = hasChanged || nextStateForKey !== previousStateForKey } // Return state data return hasChanged ? nextState : state } }
The reducers received by combineReducers are objects whose value is a child reducer function. The key value of an object can be identical to or different from the function name. The key value of the returned state is consistent with the key value of the reducers object.
So when the reducer function in the createStore (reducer, preloaded State) is combined by combineReducers, when it is passed into the initial state, it should be noted that the keys of the state should be consistent with the reducers.
It can be seen that the main function of combineReducers is to pass action into all the sub-reducer functions and traverse once, while processing state slicing and merging.
Of course, there is a lot of code missing from the exception checking section, so you can refer to the detailed source code if you are interested.
Example
/* reducer */ import {combineReducers} from 'redux'; import testAsync from './testasync'; import todoList from './todolist'; const reducer = combineReducers({ testAsync, todoList }); export default reducer; /* store */ import {createStore} from 'redux'; import reducer from './reducer/index'; let store = createStore(reducer)
TesAsync, todoList} is a reducer function object, key and function name are the same. {a:testAsync,b:todoList} can also be written in this way.
The acquisition and update of state is the same as a single reducer function. Last article It has been introduced.