1, redux contains the following self-contained applications
- state: the real data source driving the application
- view: UI declarative description based on the current state
- actions: events that occur in the application based on user input and trigger status updates
2, Unidirectional data flow
- state is used to describe the status of an application at a specific point in time
- Render View based on state
- When something happens (for example, the user clicks a button), the state will be updated according to what happens and a new state will be generated
- Re render the View based on the new state
3, Immutability
JavaScript object s and array s are variable by default. Examples are as follows:
const obj = { a: 1, b: 2 } // It is still the object, but its content has changed obj.b = 3 const arr = ['a', 'b'] // Similarly, the contents of the array are changed arr.push('c') arr[1] = 'd'
JavaScript object s and array s want to be updated immutably
----------You can copy the original object/array by using the , expansion operator , and then update its copy
const obj = { a: { // For the sake of security, update obj a. C. you need to make a copy first c: 3 }, b: 2 } const obj2 = { // Backup of obj ...obj, // Covering a a: { // obj. Backup of a ...obj.a, // Cover c c: 42 } } const arr = ['a', 'b'] // Create a backup of arr and splice c to the end. const arr2 = arr.concat('c') // Alternatively, you can create a replica of the original array const arr3 = arr.slice() // Modify copy arr3.push('c')
Redux expects all status updates to be immutable
4, Terminology
1. Action
action , is a common JavaScript object with , type , field, which describes what happens in the application
type: (string) is a descriptive name of action:
For example: action type="todos/todoAdded"
"Domain / event name", where todos is the feature or category of the action, and todoaded is the specific event.
payload: contains additional information about what happened
const addTodoAction = { type: 'todos/todoAdded', payload: 'Buy milk' }
2. Action Creator
Is a function that creates and returns an action object. Its purpose is to let you not have to write action objects manually every time:
const addTodo = text => { return { type: 'todos/todoAdded', payload: text } }
3. Reducer
reducer , is a function that receives the current , state , and , action , objects, determines how to update the state if necessary, and returns a new state: (state, action) = > new state
reducer is similar to an event listener, which processes events according to the received action type.
reducer principle:
- Only the state and action parameters are used to calculate the new state value
- Direct modification of state is prohibited. Immutable updates must be made by copying the existing state and changing the copied value
- Prohibit any code that uses asynchronous logic, relies on random values, or causes other "side effects."
The internal logic of the reducer function usually follows the following steps:
const initialState = { value: 0 } function counterReducer(state = initialState, action) { // Check whether the reducer cares about this action if (action.type === 'counter/increment') { // If yes, copy ` state` return { ...state, // Update the state copy with the new value value: state.value + 1 } } // Return to the original state unchanged return state }
Reducer can use any type of logic internally to determine what the new state should be, such as if/else, switch and loop
4. Store
The current status of the Redux application exists in an object named store.
The store is created by passing in a reducer, and has a method called getState, which returns the current state value
import { configureStore } from '@reduxjs/toolkit' const store = configureStore({ reducer: counterReducer }) console.log(store.getState()) // {value: 0}
5. Dispatch
The only way to update the state is to call store Dispatch () and pass in an action object
store will execute all reducer functions and calculate the updated state. Call getState() to get the new state.
store.dispatch({ type: 'counter/increment' }) console.log(store.getState()) // {value: 1}
Call action creator to call action
// action creator const increment = () => { return { type: 'counter/increment' } } store.dispatch(increment()) console.log(store.getState()) // {value: 2}
6. Selector
The selector} function can extract the specified fragment from the store status tree. As the application becomes larger and larger, it will encounter that different parts of the application need to read the same data. The selector can avoid repeating such reading logic
const selectCounterValue = state => state.value const currentValue = selectCounterValue(store.getState()) console.log(currentValue) // 2