Supplement to React routing and use of Redux

How to route parameters

pramse pass parameter

  • Route definition method: < route path = '/ About/:id' component = {about} / >

  • Link component: < link to = "/ path / pass parameters through pramse" > about
    When passing parameters using params, you will clearly see that the parameters are displayed in the form of routing, for example:

  • http://localhost:3000/home/message/ User 1 / Article 32
    If you want to pass objects, you can use JSON Stringify(), which you want to convert into a string, and then another page receives it with JSON Parse() turns back. Here is a brief mention, not repeated.

Pass the search parameter

This is the request method that relies on get.

  • http://localhost/home/message?id=1&title=abc

That is, can javascript get the url? The following request body. So we can modify the tags returned in the above map as follows

<li key={item.id}><Link to={`/home/message/detail?id=${item.id}&title=${item.title}`}>{item.title}</Link></li>

And this method does not need to declare reception in the route.
Receive through location in props
query

  • Route definition method:

  • Link component < link to = '/ home? id=KaTeX parse error: Expected 'EOF', got '&' at position 3: {}& ̲ title={}’’>Home
    state

  • Route definition method:

  • Link component: < link to = {{pathname: '/ Home', state: {parameters passed}} > Download

  • Get parameter: this props. location. state

- . The withRouter component enables general components to have the jump function of routing components

Sometimes, we want to use the function of the routing component in other components, such as the navigation bar, which should belong to the public component, but the function of the navigation link is the function of the routing component. How should we solve it?
In the react router, a method is provided to enable general components to have the function of routing components, which is the withRouter() method.
Look at the demo:

import {withRouter} from "react-router-dom";

class Header extends Component {
    // After withRouter, the component also has the function of routing component
    goBack = ()=>{
        this.props.history.goBack();
    }
    go = ()=>{
        this.props.history.go(2);
    }
    goForward = ()=>{
        this.props.history.goForward();
    }
    render() {
        return (
            <div>
                <h1>This is a React-router-dom Test!</h1>
                <button onClick={this.goBack}>goBack</button>
                &nbsp;
                <button onClick={this.goForward}>goForward</button>
                &nbsp;
                <button onClick={this.go}>go</button>
            </div>
        )
    }
}

// withRouter is used to add routing component specific functions to general components and return a new component
export default withRouter(Header);

The external chain picture transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-7wReIXDU-1627644504523)(image/QQ%E6%B5%8F%E8%A7%88%E5%99%A8%E6%88%AA%E5%9B%BE20210729191109.png)]

Suppose our components are like this figure, and they are nested with each other.
At this time, a request is put forward. How should the data in component E be processed to be used by component A and component F?

  • Method 1: transfer parameters through continuous props, but it is very time-consuming and laborious
  • Method 2: use PubSub JS, etc
  • Method 3: use react Redux for centralized data management

That is, redux can be regarded as a housekeeper, responsible for helping to store public data.

10, Use of redux

Suppose our components are like this figure, and they are nested with each other.
At this time, a request is put forward. How should the data in component E be processed to be used by component A and component F?

  • Method 1: transfer parameters through continuous props, but it is very time-consuming and laborious
  • Method 2: use PubSub JS, etc
  • Method 3: use react Redux for centralized data management

That is, redux can be regarded as a housekeeper, responsible for helping to store public data.

. install redux

npm i redux -S

2. Core concepts


redux has three core concepts

  1. action
    

    :

    • Action object (operation content)
    • It contains two attributes: a. type: indicates the attribute, the value is a string, unique and necessary attribute (what to do) b. data: data attribute, the value is of any type, and optional attribute (how to do it)
    • For example: {type: "add_student", data: {Name: "Tom", age: 18}}
  2. reducer
    

    :

    • Used for initialization status and machining status (initialization and operation of data)
    • During processing, a pure function of a new state is generated according to the old state and action
    • There are two parameters, one is the previous state (prevstate) and the other is the action object (action)
  3. store
    

    :

    • Object (brain) that links state, action and reducer together

We can roughly imagine redux as a restaurant, and we are the customers. We call the waiter (action) to order and other operations. After the waiter sends it to the manager (store), the manager instructs the back kitchen (reducer) to cook, and then the manager passes it to the customers after the dishes are cooked

3. Basic use of redux

(1) Create folder

Create a Redux folder in the src folder to store the related contents of redux

  • Compnoent ------ folder for storing components

  • redux

    ------Store

    redux
    

    Folder of related content

    • actions ---- the folder where action related contents are stored
    • reducers ---- the folder where reducer s are stored
    • constant.js ---- store files with standard names
    • store.js ---- write the file of the store

I'll take you one by one. First write the simplest redux

/**
 * store.js
 * This file is specially used to expose a store object. The whole application has only one store object
 */
// createStore is introduced to create the most core store in redux
import {createStore} from "redux";
// Introduce reducer serving Count component
import countReducer from "./count_reducer";
const store = createStore(countReducer)
// Expose store object
export default store;
Copy code
/**
 * / reducer / count.js
 * 1. This file is used to create a reducer serving the Count component. The essence of the reducer is a function
 * 
 * 2. reducer The function will receive two parameters: the previous state and the action object
 * 
 * 3. It will automatically call reducer (initialization) once
 */
// Status of initialization
const initState = 0;
export default function countReducer(preState = initState, action){
    if(preState === undefined) preState = 0; 
    // Get type and data from the action object
    const {type, data} = action;
    // How to process data according to type
    switch (type) {
        case 'increment': // data
            return preState + data;
        case 'decrement': // If it is minus
            return preState - data;
        default:
            return preState;
    }
}
Copy code
// / Component / Count.js 
import React, { Component } from 'react'
// Introducing store
import store from "../../redux/store";
export default class Count extends Component {
    // addition
    increment = ()=>{
        const {value} = this.selectNumber;
        // Send action object to store
        store.dispatch({
            type: "increment",
            data: value*1
        })
    }
    render() {
        return (
            <div>
                <h1>The current summation is:{store.getState()}</h1>
                <select ref={c=>this.selectNumber = c}>
                    <option value="1">1</option>
                    <option value="2">2</option>
                    <option value="3">3</option>
                </select>
                <button onClick={this.increment}>+</button>
            </div>
        )
    }
}

This must be added, otherwise the data will change, but the page will not change

 componentWillMount(){

       console.log(store.subscribe)

        store.subscribe(()=>{

          this.setState({})

      })

   }
This code must be added, otherwise render The function does not call and the page does not change

The above is the most streamlined redux. Let's analyze the process:

  1. Write the Count component and create the Reducer file corresponding to the Count component

  2. to write

    Reducer
    

    And throw:

    • Reducer is a pure function
    • Switch is usually used to judge the type in action
    • The return value of the function is the modified value
  3. establish

    store
    

    And write code:

    • Use the createStore() method to create a store. The parameter is a reducer
    • Import the reducer of the prepared Count component
  4. Introducing in components

    store
    

    And call:

    • In the method, pass the action to the store by using the dspatch() method
    • The parameter of dispatch is an object (i.e. action object)

(2) Use process

The above general process is created, and the general process used is as follows:

  1. When the store is initialized, the reducer is automatically called once to initialize the value
  2. The component sends an action to the store, and the store judges and distributes it to the corresponding reducer
  3. The reducer processes the data according to the type in the action and returns a new value
  4. store receives the returned new value and replaces the old value
  5. Through the method store Getstate() gets the value of the current store

(3) Using asynchronous redux

If we need to use asynchronous redux, we also need to use another plug-in: redux thunk

npm i redux-thunk -S
 Copy code

This is a middleware used to help handle asynchronous redux,
The value of asynchronous action is a function in which ordinary dispatch() operations are performed

export const createIncrementAsyncAction = (data, time=500)=>{
    // Return an action
    return ()=>{
        setTimeout(()=>{
            store.dispatch(createIncrementAction(data));
        }, time);
    }
}
Copy code

At the same time, we need to set the store to support the execution of middleware. The middleware can be loaded through the applyMiddleware() method of redux. Its parameter is the middleware, and then applyMiddleware() will be introduced as the second parameter of createStore().

// store.js
// applyMiddleware is introduced to execute middleware
import {createStore, applyMiddleware} from "redux";
// Introduce reducer serving Count component
import countReducer from "./count_reducer";
// Redux thunk is introduced to support asynchronous action s
import thunk from "redux-thunk";
// Expose store object
export default createStore(countReducer, applyMiddleware(thunk));
Copy code

(4) Monitoring state change

Did you find that although the status in redux has indeed been updated, the page has not changed?
Remember which function is used for page rendering? render() function. However, when the state of redux changes, it will not help us call the render () function, so we need to manually render the page in real time.
Here, we use the subscribe() method on the store of Redux to listen for changes in the state of redux. The parameter is a function to facilitate our operation.
Generally, we write it on the root tag (it's simpler, so we don't have to write it again in every component using redux)

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import store from "./redux/store"
ReactDOM.render(
    <App />,
  document.getElementById('root')
);
// Simplified writing
store.subscribe(()=>{
  ReactDOM.render(
      <App />,
    document.getElementById('root')
  );
})

4. Precautions

  1. Generally, if you use redux, you must use more than one component, so you create actions and reducers to store multiple actions and reducers

  2. ditto,

    store
    

    There must be more than one loaded

    reducer
    

    So we use

    redux
    

    of

    combineReducers()
    

    Methods to integrate all

    reducer
    
    • The parameter of the combineReducers() method is an object in which all reducers are stored
import {createStore, applyMiddleware, combineReducers} from "redux";
import countReducer from "./reducers/count";
import personReducer from "./reducers/person";
import thunk from "redux-thunk";
// Summarize all reducer s
const allReducer = combineReducers({
    count: countReducer,
    persons: personReducer,
});
export default createStore(allReducer, applyMiddleware(thunk));
  1. because

    redux
    

    There are still many problems in the design, such as:

    • A single component needs to do: deal with the store, obtain data, monitor data changes, dispatch action objects, etc. a component is responsible for too many things.
    • Additionally, you need to monitor the status changes of redux to update the status and render the page.
    • Therefore, someone has optimized redux and launched another library, react redux (rest assured, it's no different, just a little more optimization, which will be discussed later)
  2. If you can't use redux, don't use redux (either redux or react redux)

  3. If you can't use redux, don't use redux (either redux or react redux)

  4. If you can't use redux, don't use redux (either redux or react redux)

summary

redux is a state library for managing react data. When we need to use the same set of data in many places, we can use redux to manage our data, avoiding unnecessary multi-level and complex data transmission, making our data more convenient, efficient and saving memory space

Keywords: React

Added by stupid girl! on Mon, 03 Jan 2022 23:12:42 +0200