What is the story
Redux is a JavaScript state container that provides predictable state management.
It says: Web application is a state machine, view and state correspond one to one. UI = render(state) UI = render(state)
Why use Redux
Today’s Web applications involve a large amount of data interaction, asynchronous operations, etc., which undoubtedly increases the complexity of the front end and requires more and more state maintenance. Redux, on the other hand, tries to make every state change predictable, unifying all actions and states in an application.
Redux’s three rules
- The entire application state should be stored in a single Store for a single data source.
- The only way to change the state of a Store is to trigger an Action object.
- Data change through pure function action change state through reducers.
Redux workflow
Before talking about the Redux workflow, it is important to understand several core concepts related to Redux:
- Action: An Action can be thought of as an application notification that the State is about to change. An Action can be triggered either by the user’s Action on the View layer or by the server’s response.
- Action Creator: If there are many kinds of actions and it is cumbersome to write each one by hand, use the defined Action Creator function to generate the Action.
- Dispatch: The only way an Action can Dispatch.
- Store: The only place in the entire app where data is stored.
- State: Generates a snapshot of the data stored in the Store at a point in time. This data set is called State.
- The Reducer: Action simply describes how State should be changed, whereas the Reducer does how State should be changed.
Specific workflow: The user triggers the Action through the View (or server response). The Action generated by the Action Creator function is dispatched to the Store by the Dispatch method. The Store automatically calls the Reducer and passes the current State and Action to it. The Reducer returns the new State. If the State changes, the Store will update the View using the listener function. To illustrate this process, let me use a graph:
Strictly unidirectional data flow is at the heart of the Redux architecture.
Several examples of Redux core concepts
Take the example of an Action that responds to the content of an article from the server
const LOAD_ARTICLES_DETAIL = 'LOAD_ARTICLES_DETAIL'
const LOAD_ARTICLES_DETAIL_SUCCESS = 'LOAD_ARTICLES_DETAIL_SUCCESS'
const LOAD_ARTICLES_DETAIL_ERROR = 'LOAD_ARTICLES_DETAIL_ERROR'
Copy the code
Action Creator
export const loadArticlesDetail = (a)= > ({
type: LOAD_ARTICLES_DETAIL
})
export const loadArticlesDetailSuccess = result= > ({
type: LOAD_ARTICLES_DETAIL_SUCCESS,
result
})
export const loadArticlesDetailFailure = error= > ({
type: LOAD_ARTICLES_DETAIL_ERROR,
error
})
Copy the code
Store
const store = createStore(reducers)
Copy the code
Reducer (previousState, action) => (newState)
export default (state = initalState, action) => {
switch (action.type) {
case LOAD_ARTICLES_DETAIL: {
return {
...state,
loading: true.error: false}}case LOAD_ARTICLES_DETAIL_SUCCESS: {
return {
...state,
loading: false.error: false.articlesDetail: action.result
}
}
case LOAD_ARTICLES_DETAIL_ERROR: {
return {
...state,
loading: false.error: true}}default:
return state
}
}
Copy the code
Dig deep into the Redux source code
Redux main source overall structure:
- The entry file is index.js
export {
createStore,
combineReducers,
bindActionCreators,
applyMiddleware,
compose
}
Copy the code
This is how the entry file is exported, and this is how Redux supports it. These methods are implemented in the main workflow file and the helper function file.
- The main workflow file createstore.js is the createStore method that generates the Store, so let’s see what it does:
- The getState method returns the current State
- The subscribe method passes a function to the listener queue and returns an unsubscribe function
- The dispatch method calls Reducer, executes the listener in sequence, and returns the Action auxiliary source file:
- Applymiddleware.js: Used to enhance Store
export default function applyMiddleware(. middlewares) {
return (createStore) = > (reducer, preloadedState, enhancer) => {
const store = createStore(reducer, preloadedState, enhancer)
let dispatch = store.dispatch
let chain = []
const middlewareAPI = {
getState: store.getState,
dispatch: (. args) = >dispatch(... args) } chain = middlewares.map(middleware= >middleware(middlewareAPI)) dispatch = compose(... chain)(store.dispatch)return {
...store,
dispatch
}
}
}
Copy the code
From the source, it finally returns a Store and an updated dispatch method to enhance the Store.
- BindActionCreators. Js:
export default function bindActionCreators(actionCreators, dispatch) {
if (typeof actionCreators === 'function') {
return bindActionCreator(actionCreators, dispatch)
}
}
Copy the code
Use Dispatch to wrap all action Creators so they can be called directly.
- Combinereducers. js: Split the Reducer when the application is large, but the Reducer passed to the Store must be a function, so this method is used to merge multiple reducers.
- compose.js
export default function compose(. funcs) { if (funcs.length === 0) { return arg= > arg } if (funcs.length === 1) { return funcs[0]}return funcs.reduce((a, b) = >(... args) => a(b(... args))) }Copy the code
The compose method, the string of functions that are passed in, the end result of the execution is to concatenate the functions.
Conclusion:
- Redux is a JavaScript state container that provides predictable state management.
- Strictly unidirectional data flow is at the heart of the Redux architecture.
- UI = render(state)