preface
Redux is a container for managing state, a state management solution that can be used with any front-end framework. For the most part, we use Redux on a React basis. The React-Redux library provides components such as Providers and connect, which make it easy to use Redux in React.
This article only deals with Redux, and another article may be written to analyze React-Redux.
The body of the
Note: The Redux source code shown below is simplified
Store
What Redux does is very simply provide a place to store state and send notifications when state changes. This place to store state is conceptually called a store. We can implement a store through the createStore method.
First, take a look at the createStore method in Redux.
function createStore(reducer, initialState) {
// Initial state
let state = initialState
// The subscription function
let listeners = []
/ / subscribe
function subscribe(listener) {
listeners.push(listener)
// Unsubscribe
return function unsubscribe() {
const index = listeners.indexOf(listener)
listeners.splice(index, 1)}}// Change the state
function dispatch(action) {
/ / update the state
state = reducer(state, action)
// Trigger the subscription function
for (let i = 0; i < listeners.length; i++) {
const listener = listeners[i]
listener()
}
}
/ / for the state
function getState() {
return state
}
return {
subscribe,
dispatch,
getState
}
}
Copy the code
As you can see, the Store not only stores state data, but also provides a way to change state and listen for actions.
Redux uses a publish-subscribe model for notification of status changes. In this case, state is used to hold state; The subscribe method stores functions to listeners. The Dispatch method is used to change state and call functions subscribed to by listeners.
In practice, we first call the createStore method to create a store and the createStore receives two parameters reducer and initialState. InitialState is an initialState, such as 0, ‘Jack’, or an object, such as {count: 1}. So what is Reducer?
Reducer & Action
Dispatch method in createStore.
function dispatch(action) {
state = reducer(state, action)
// ...
}
Copy the code
We can see that when we call Dispatch to change the state, the value is not randomly assigned to state, but through a layer of reducer processing.
Reducer makes state changes manageable and the final state predictable. For example, take Reducer as a factory that provides several production lines. We only need to tell Reducer the raw materials and which production lines we need to go. The raw material and the scheduled line are included in the Action.
Here is a simple example.
function reducer(state, action) {
switch (action.type) {
case 'INCREASE':
return state + 1
case 'DECREASE':
return state - 1
default:
return state
}
}
const action = { type: 'INCREASE' }
const store = createStore(0, reducer)
store.dispatch(action)
console.log(store.getState()) / / 1
Copy the code
It can be seen that with Reducer and action, we will not change the state to any value at will, but select a production line from the Reducer factory, process the state and get the final state. The so-called predictable.
To sum up, the core content of Redux includes Store, Reducer and action.
combineReducers
In real projects, there must be more than one state, dozens or hundreds of states are common. If so many states were only dealt with by a Reducer method, it would be unacceptable. Redux provides a combineReducers method that integrates multiple Reducer methods. In this way, we can split up the state and manage it. The following is a simplified combineReducers source code.
function combineReducers(reducers = {}) {
// An array of state names
const keys = Object.keys(reducers)
// Return to the merged Reducer method
return function combination(state, action) {
const nextState = {}
// Iterate over each state and make updates
keys.forEach(key= > {
const reducer = reducers[key]
const previousStateForKey = state[key] / / the old state
const nextStateForKey = reducer(previousStateForKey, action) Call the corresponding reducer to get the new state
nextState[key] = nextStateForKey
})
return nextState
}
}
Copy the code
Take a simple example.
function count(state, action) {
switch (action.type) {
case 'INCREASE':
return state + 1
case 'DECREASE':
return state - 1
default:
return state
}
}
function name(state, action) {
switch (action.type) {
case 'SET_NAME':
return action.name
default:
return state
}
}
const reducer = combineReducers({ count, name })
Copy the code
conclusion
The principle of Redux is to publish and subscribe, itself is very simple, the amount of source code is also very small, easy to learn, mainly experience its ideas.