1. Three common approaches in REdux
- GetState (), which gets the tree of state objects
- Dispatch (), which dispatches synchronized actions
- Subscribe (), which calls the callback function when some property in the state tree changes and rerenders
/** * First, the return value of this function is an object, since it is called with store.getState(), so the return object has three attributes must be the function */
export function createStore(reducer) {
let state // Save the state object tree
const listeners = [] // Save all subscribe callback functions
state = reducer(state, {type: '@mini'})
function getState() {
return state
}
function dispatch(action) {
// Replace the original state with the new state obtained by the reducer function
state = reducer(state, action)
// Call all subscribe callback functions to achieve the effect of re-rendering
listeners.forEach(listener= > {
listener()
})
}
// Save all subscribe callback functions, and call all SUBSCRIBE callback functions when calling Dispatch to change the property state, to rerender the effect
function subscribe(listener) {
listeners.push(listener)
}
return {getState, dispatch, subscribe}
}
Copy the code
2. The second important thing in the Redux library is to combine reducer functions
Note that it integrates all the reducer functions and is itself a reducer. The return value of all this function is a reducer function code:
export function combineReducers(reducers) {
// Because the reducer function is returned, it has state and action parameters, where state is the total state tree and action is the action passed in by Dispatch
/** * state = { * count: 0, * msgs: [] * } */
return function (state = {}, action) {
// Because each reducer function is processed, the return value is the new state of the reducer function, so finally all the sub-states form a new state tree, which is used to save the new total state tree
const newState = {}
Because combineReducers is passed in an object, and the attribute value of each attribute is a Reducer function named after the attribute name, all keys are traversed to obtain all key names, and each key name is also the name of each reducer function
const keys = Object.keys(reducers)
// Iterate over the array of keys again
keys.forEach(key= > {
// Find the Reducer function for each child
const childReducer = reducers[key]
Because each function is a reducer function, we need a state object and a synchronization action, which is passed in by the user, while the substate is an attribute on the total state
const childState = state[key]
// Call the reducer function and return a new child state
const newChildState = childReducer(childState, action)
// Store the new child state into the new total state that needs to be returned at last
newState[key] = newChildState
})
return newState
}
}
Copy the code
To simplify the above code:
export function combineReducers(reducers) {
return function (state = {}, action) {
return Object.keys(reducers).reduce((newState, reducerName) = > {
newState[reducerName] = reducers[reducerName](state[reducerName], action)
return newState
}, {})
}
}
Copy the code