References:

Juejin. Cn/post / 684490…

Juejin. Cn/post / 692650…

1. redux

React has props and state:

  • Props means properties that are distributed by the parent
  • State means the state that can be managed internally by the component, and the entire React does not have the ability to trace data upward. This is the one-way data flow of React

This means that if it is an application with very complex data states, it is often found that React cannot allow the two components to communicate with each other and use each other’s data. React’s method of transferring data through hierarchies is very uncomfortable.

In the project, we often have such a requirement, according to the current login user information display different menus or data, this requires that we can obtain the login user information in any component, how to do? If there is no such framework, we will certainly try to find a way to store the global information in a unified place, design the corresponding data structure exists in a JS object, and this object must be singleton, to ensure that the data obtained each time is the same. For modification logic, there are also established rules to be followed to ensure that every data modification is traceable. Without the conventions of these rules, state (data) changes become chaotic, code becomes chaotic, and potential problems with the system multiply.

At this point, there is an urgent need for a mechanism that centralizes all the states at the top of the component, and has the flexibility to distribute all the states as needed to all the components. Yes, this is Redux

(1) Introduction of redux mechanism

  • actions

    A function that returns an action object, usually with a type attribute. Responsible for the generation of instructions, the page through store.dispatch(action) to send data modification requests to the store.

  • reducers

    A pure function that takes two arguments (previousState, action), the first of which represents the value of the previousState. Action is the action passed from the previous page to the store via store.dispatch(action). Reducers handles the action’s type value differently, returning a new variable, newState. Reducers cannot directly modify the previousState passed in.

  • store

Pass const store = createStore(Reducer); Create a Store object. To import the React component file, run this.state = store.getState(); Let the component get the data in the store;

The whole process is redux’s three principles:

  • Single data source: Data in a store is singleton and globally unique.
  • State is read-only: the only way to change State is to trigger action, store.dispatch(action); Modifying state directly does not work.
  • Reducers are pure functions that ensure that the results of repeated implementation are the same under the premise of (previousState, Action) determination; Instead of directly modifying the state, the Store triggers the change of state.

(2) Basic use

  1. Create the reducer

    A single reducer can be used or multiple reducers can be combined into a reducer, that is, combineReducers() action puts the state into the Reucer processing function and returns the new state to process the state

  2. Create an action

    Therefore, this action can be understood as an instruction. As many instructions need to be issued, the action is an object and must have a parameter called type to define the action type

  3. Create a store using the createStore method

    Store can be understood as a total factory with multiple processing machines providing subscribe, dispatch, getState and other methods.

2. react-redux

React-redux is a combination of React and Redux. Its core idea and mechanism remain unchanged

(1) Set action and actionType

Aciton is responsible for defining behaviors and distributing changed data and behaviors to Store, which is then sent to Reducer by Store. Reducer identifies behaviors and receives data

Here, we unify actionType and Aciton.

actionType.js: aciton.js Type indicates what the current action is intended to do to distinguish between different actions that change store data (such as increasing money).

Data represents the parameters that need to be carried by the aciton behavior of the target, or the specific value that needs to be modified (such as adding 500 dollars of money).

(2) Set reducer

The Reducer is responsible for processing the specified states based on the differentiation of the specified actions.

Generally speaking, each Reducer is a pure function and represents a state data. It takes two parameters by default (the current state value, the action passed in).

The current state is typically assigned a default value, and each subsequent update is processed based on the current state value and returns a logical new state value. It then hands it to store for the corresponding state update and then updates the current state value

reducer.js

(3) Create store and inject global

Only store is responsible for updating state, and Reducer must be a pure function. Reducer is responsible for the processing logic and returns a newstate to the store, which then updates itself;

Stores must be unique. Multiple stores are not allowed

store.js

After exposing store.js and passing it to the props of the top-level component app.js, introduce the React-Redux Provider inside the top-level component and pass it to the Prop Store

App.js (Top-level component)

(4) Use Store data in the component and update Store data

The following three functions are needed:

  • MapStateToProps function to convert the state in a store to the props of a component
  • The mapDispatchToProps function, which passes in dispatch to trigger the action.
  • The connect function.
const mapStateToProps = (state) = >({
    inputValue: state.inputValue,
    list: state.list
})

const mapDispatchToProps = (dispatch) = > ({
    hanldeAdd: () = >{
        dispatch(addItem());
    },
    changeInputValue:  (e) = >{
        dispatch(changeValue(e.target.value));
    },
    deleteItem: (key) = >{
        dispatch(deleteItem(key))
    }
})
MapStateToProps and mapDispatchToProps
// And returns a function that accepts TodoList to return a wrapped component.
export default connect(mapStateToProps, mapDispatchToProps)(TodoList);

Copy the code

(5) Redux-thunk

If the original redux workflow is followed, reducer modification state will be directly triggered when an action is generated in the component. Reducer is a pure function, that is, no asynchronous operation can be performed in reducer.

In practice, an asynchronous task needs to be completed before the actions in the components enter the reducer, such as sending ajax requests and receiving data, and then entering the reducer. Obviously, native Redux does not support this operation

Redux provides a middleware called Redux-Thunk that allows us to “play around” with actions and reducers, processing asynchronous requests first and then triggering dispatch to initiate operations to the store.

Add middleware redux-thunk to store:

import { createStore, applyMiddleware } from "redux";
import thunk from "redux-thunk";
import reducer from ".. /reducers";

const store = createStore(reducer, applyMiddleware(thunk));

export default store;

Copy the code

Use asynchrony in an aciton:

// actionCreator.js
export const getInitList = () = > {
    return function(dispatch){
        axios.get("/api/initList.json").then(res= >{
            dispatch(initList(res.data))
        })
    }
}

Copy the code