1. Basic knowledge

2. The virtual DOM + DIff algorithm will only manipulate the changed content. JSX => JSX => JSX => JSX => JSX => JSX => JSX The difference between an expression and a statement is that you can take a variable and connect itCopy the code

2. Basic knowledge of classes

This in the constructor refers to the instance object of the class; Methods defined in a class are placed on the class's prototype object, and instances can be accessed and used through the prototype chain; The method this defined in the class points to the instance object of the call. If a subclass inherits a parent class and has a constructor in it, then the constructor must say super to help you get the properties of the parent class;Copy the code

3. Why do events in react class components need to bind this

class Weather extend React.component {
    constructor(props) {
        // This in the constructor points to the instance object
        super(props);
        this.state = {}
    }
    // As an event callback for onClick, this function is called directly, not on an instance object, so this is undefined (strict mode is enabled by default, so it does not point to window)
    changeWeather(){... }render(){
        // Render is a class method called by the Weather instance object in the react background, so this also refers to the instance object
        return <h1 onClick={this.changeWeather}>test</h1>}}Copy the code

Solution: 1. Bind this to the constructor

constructor(props) {
    // The changeWeather on the right and right of the assignment statement is a method defined in the class that follows the prototype chain.
    // On the left side of the assignment, the changeWeather method is defined in the instance object, so both the prototype and the instance object itself have this method.
    // Summary: We created a new method in the constructor based on the method in the class and changed its this reference
    this.changeWeather = this.changeWeather.bind(this);
}
Copy the code

2. Write assignment statements directly in the class

class Women extends React.Component  {
   // Add an attribute to the instance object of the class
   sex = 'woman'
   
   // In the same way, assignment statements can also assign functions.
   changeWeather = function() {
      // But this does not solve the problem, because the function is still called directly as an event, and this still cannot point to an instance object
      console.log(this)}// We can solve this problem by using the arrow function
   changeWeather =  () = > {
       // The arrow function doesn't have this, it looks for this in the outer environment of the code, which is the instance object.
      console.log(this)}}Copy the code

From above, we can abbreviate state,

class Women extends React.Component  {
    // Initialize state
   constructor(props) {
       super(props);
       this.state = {sex: 'woman'}}// Initialize state with assignment
   state = {sex: 'woman'}}Copy the code

4. Other items for attention

OnClick ={demo()} will execute immediately. Since React executes the render method, onClick will be assigned when it reads this sentence. The result of the assignment is the value returned on the right-hand side. If you write demo(), you will execute this function and return undefined as the callback, so you cannot write (). You will update this function as the onClick callback setState by merging it. The constructor doesn't update, but Rander calls it every time it updates;Copy the code

5. Batch delivery of props

If you need to pass multiple properties to components, you can pass them in the form of object destruct assignments, which is the syntactic sugar provided by React

let b = {name: 'x'.age: 18}

console.log(... b)/ / an error<Persn {... b} />React syntax sugar
Copy the code

Note: The expansion operator cannot be used to expand an object. It can only be used to copy attributes of the object to a new object, such as a = {… B}. React {} is a delimiter, indicating that the contents of the react tag are expressions. B is actually an expression. Js does not support extending operators to expand objects like arrays. React expands objects in some ways

// We can also use the expansion operator to batch fetch parameters
function sum(. number){
   console.log(number); / / / [1, 2, 3, 4]
}
sum(1.2.3.4);
Copy the code

6. Rule restrictions on props

Add the propTypes attribute to the class itself

class Person extends React.Component  {... }// Add type and necessity constraints
Person.propTypes = {
    name:Proptypes.string.isRequired
    speak:Proptypes.func, // Note the function notation
}
// Add the default value
Person.defaultProps={
    sex: 'male'};// This is not an elegant way to write. Static adds an attribute to a class; unadds an attribute to an instance
class Person {
    staticpropTypes = {... }// Add type and necessity constraints
    staticdefaultProps = {... }// Add the default value
}
Copy the code

7. Attention items for other props

Constructors in React need to be declared in two cases: 1. 2, bind the event instance (this); We can solve both of these cases by writing assignments directly. So the constructor may or may not write. When is super (props) needed? Only when we need to use this. Props in a constructor, we rarely need functional components to pass props directlyCopy the code

Refs is used to get DOM nodes

1. String: Add the ref attribute to the tag. This. However, the ref of string has been abandoned by the official website, which has some efficiency problems.

2, callback function type:

<input ref={(curNode) = >{this.input1 = curNode}} />
Copy the code

This format causes the callback function to be called every time the status is updated. The solution is as follows (it doesn’t really matter)

setInput = (c) = > {
this.input1 = c;
}
<input ref={this.setInput} />
Copy the code

4, createRef

/ / in the class
// createRef returns a container that can store the nodes represented by ref
this.myRef = React.createRef()

// In reference
<input ref={this.myRef} />
Copy the code

9, the higher-order function to achieve the event callback function data transmission parameters

A function is a higher-order function if it conforms to either of the following two specifications, 1. If function A takes A function, then A can be called higher-order function 2. If the return value of function A is still A function, then A can be called the common high-order function of high-order function, such as reduce, Map, Promise and setTimeout of array

The onChange event callback is the return value of this.saveFormData

function saveFormData (dataType) {
 return (event) = > {
    this.setState({
    [dataType]: event.detail.value
    })
 }
}
<input onChange={this.saveFormData('passWord')} / >Copy the code

10. Corrification

The encoding form of the function that continues to return the function through the function call and realizes the unified processing of the parameters received for many times is as follows

function sum (a) {
 return (b) = > {
    return (c) = > {
        return a + b + c
    }
 }
}
sum(1) (2) (3)
Copy the code

11. Class Component Lifecycle (old)

API: ReactDom unmountComponentAtNode, manual unload components mounted: ComponentWillMount () componentDidMount () componentWillUnmount () componentWillUnmount () componentWillUnmount () SetState () shouldComponentUpdate whether the state should be updated (return true or false after definition) stateState executes after the control component updates the valve. ComponentDidUpdate mandatory update: ForceUpdate () does not change the state, ComponentDidUpdate preProps preState preProps preState componentWillUpdate preProps preState ComponentWillReceiveProps components will accept a prop (not for the first time, ShouldComponentUpdate componentWillUpdate componentDidUpdateCopy the code

Class component Lifecycle (New)

Remove componentWillMount componentWillUpdate componentWillReceiveProps increase getDerivedStateFromProps get derived from props state into the refs Usage: state can be used when all props are props in any state. Returning the object attribute replaces state with the same attribute, and state cannot be modified. GetSnapshotBeforeUpdate getSnapshotBeforeUpdate Input parameter preProps preState Output parameter NULL or any value used Before the last render output (submitted to the DOM node). You can get some information from the DOM before changing, And pass it as a parameter to componentDidUpdate(preProps preState,snapshotValue)Copy the code

Keys in the virtual DOM

1. Functions of Key: 1) Find the same key in the old virtual DOM as the new one. If the content in the virtual DOM remains unchanged, the previous real DOM will be directly returned. If the content changes, a new real DOM will be generated to replace the previous DOM. If the data list is added or deleted in reverse order, the index will not correspond to the original virtual DOM, resulting in unnecessary updates to the real DOM. A DOM update error occurs if the structure also contains the DOM of the input class. The following exampleCopy the code
    this.state = {
    arr: [{id: 1.name:'xiao li'},
        {id: 2.name:'note:'},
    ]
    }
    add = () = > {
        let arr = this.state.arr;
        this.setState({
        arr: [{id: 3.name: 'wang'},... Arr]} <button onClick={add}> </button> <ul> {this.state.arr. Map ((item,index) => {return <li key={index}> {item.name} <input type="text"> }) } </ul>Copy the code

If we enter something in the input field in Li and then click the Add button to add a piece of data in reverse order, the content will be messed up. Why is that? Since we use index as the index, react diff algorithm will find that the virtual DOM with key 0 and 1 is changed, and the real DOM will be changed accordingly. But the input tag doesn’t change in the virtual DOM’s view (there are only a few descriptive properties in the virtual DOM, such as the input target.value, which are only available in the real DOM, so the virtual DOM doesn’t notice the change) and is therefore reused directly. The input under 0, 1 remains unchanged, but the text in li has changed. This creates serious bugs.

React Configure proxy

1. Cross-domain reasons

The cross-domain nature is that because of the same-origin policy, if we make a request at localhost:3000 to :5000, Ajax won’t allow it. To be precise, it is allowed to send, but not allowed to receive returned data.

2. React

Client 3000 sends a request to 5000 via Ajax, and Ajax limits it. But we can settle it by agency. An agent is a small service that opens at 3000. The request from the client is sent to the proxy service on 3000. The proxy service sends the request to the proxy service on 5000. The proxy service informs the proxy service on 3000 of the result and forwards the request to the client on 3000. The proxy is not cross-domain because the proxy does not send requests through the Ajax engine, which is the cause of cross-domain.

React configure proxy methods

Method 1: Append the following configuration to package.json proxy :"http://localhost:5000" Advantage: Simple configuration, no need to add a prefix to the request address Disadvantage: Multiple proxies cannot be configured. If 3000 resources that do not exist are requested, the request is forwarded to 5000. Method 2: create a proxy configuration file. Create a configuration file in SRC: SRC/setupproxy. jsCopy the code
   const proxy = require('http-proxy-middleware')
   module.exports = function(app) {
       app.use(
           proxy('/api1', { // All requests prefixed with/API1 are forwarded to 5000
               target: 'http://localhost:5000'.// Configure the forwarding target address (the server address that can return data)
               changeOrigin:true.// Controls the value of the host field in the request header received by the server
               /*
        	changeOrigin设置为true时,服务器收到的请求头中的host为:localhost:5000
        	changeOrigin设置为false时,服务器收到的请求头中的host为:localhost:3000
        	changeOrigin默认值为false,但我们一般将changeOrigin值设为true
                */
                pathRewrite: {'^/api1': ' '} // Remove the request prefix to ensure that the background server is a normal request address}}))Copy the code
1. Advantages: Multiple proxies can be configured to flexibly control whether requests go through proxies. 2. Disadvantages: Cumbersome configuration and prefix must be added when the front-end requests resources.Copy the code

Parameter passing across components – message subscription and publication

Introduce pubsub. Js

// Subscribe to the message
PubSub.subscribe('Message name'.(msg, data) = > {
// MSG is the name of the message, and data is the data passed in
})

// Publish the message
PubSub.publish('Message name'.'Here's the data.');

// Unsubscribe
let token = PubSub.subScribe('Message name'.() = > {})
PubSub.unsubScribe(token);

Copy the code

use

Listen on componentDidMount, unlisten on componentWillUnmount

The react routing

1. Understanding of SPA

Single Page app with multiple components

2. Understanding of routing

1) Routing is a mapping between a path and a component. Key is a mapping between a path and a component. Value is a mapping between a path and a component. Router.get (path, function(req,res)); 3) Working process: When Node receives a request, it matches the corresponding route according to the path of the request, and calls the function of the route to process the request and return the response data. <Route path='/test' Component ={test} 3) {Route path='/test' component={test} When the browser's path changes to test, find the test component and render itCopy the code

3. Principle of front-end routing implementation

The implementation of front-end routing is BOM based history, which stores historical routes like a stack and can detect route changes. History is divided into browser routes BrowserHisotry and HashHistory

4, the react – the route – the dom

The routing component can receive three important parameters about the router: history location match [root@localhost] [root@localhost] [root@localhost] [root@localhost] [root@localhost] [root@localhost] [root@localhost] [root@localhost] Redirect redirect is not displayed at the bottom of all route registers. The redirect is not displayed at the bottom of all route registers. The redirect is displayed at the bottom of all route registers. When all routes do not match, redirect the specified route. 4. <Link to='/demo/test/ Tom /18'></Link> <Route path="/demo/test/:name/:age" Component ={test}/> Const {name, age} = this.props.match.params <Link to='/demo/test? Name =tom&age=18'></Link> Register Route without declaration, register normal: <Route path="/demo/test" component={test}/> Const {search} = this.props. Location Note: Search is a Urlencoded string, queryString is needed (qs.parse)  <Link to={{pathname:'/demo/test', state: {name: 'tom', age: {Route path="/demo/test" component={test}/> Const {name, age} = this. Props. Location. Note: the state <Link replace to='/demo/test'></Link> 9. Programmable route navigation Use the API on the this.props. History object to manipulate routing. Push, replace, goBack, goForward, Go, etc. 10. WithRoute provides routing component-specific apis for generic components. The return value of withRouter is a new component, exported for use. BrowserRouter uses H5's History API. Hashrouters that are not compatible with IE9 and below use hash urls and do not make requests to the server. 2) Path does not have # numbers in BrowserRouter 3) Impact on route state parameters BrowserRouter does not have impact, but hashRouter does lose stateCopy the code

redux

Three core concepts

action

The action object has two attributes: Type and data. Type is the unique identifier of the event distributed, and data is the data carried

reducer

Used to initialize the state and generate a new state based on the old state and action. The parameters are preState and action.

Reducer must be a pure function, that is: 1. Parameter data cannot be changed; 2. No side effects, such as network requests, input and output devices; 3Copy the code
store

The linkage of state, Action and Reducer, with many apis, is the core of VUEX

The basic flow
// Component A dispatches action
import store from '/redux/store
import {createIncrementAction} from '/redux/_action
increment = () = > {
    store.dispatch(createIncrementAction(1))}Reducer initialize the state and generate a new state.
const initState = 0
export default function countReducer(preState=initState, action) {
  const { type, data } = action;
  switch (type) {
    case "increment":
      return preState + data;
    default:
      return preState
  }
}

// Create a store and pass it to reducer
import {createStore} from 'redux'
import countReducer from './count_reducer'
const store = createStore(countReducer);
export default store;

// Component B uses state
import store from '/redux/store'
// Listen for store changes and call render to render updated data (because redux is only responsible for managing state, not driving page changes)
// With react-redux, there is no need to manually listen. The container generated by the CONNECT API will provide this functionality
componentDidMount() {
    store.subscribe(() = > {
      this.setState({});
    });
 }
 // The component uses state
<div>{store.getState()}</div>
Copy the code

react-redux

concept

  • Distinguish between UI components and container components. The React UI component is the React component, and the react container component is the component generated by Redux using the Connect API to connect the Redux and React components.
  • Container components can use redux’s API and pass state and methods for manipulating state to UI components via props

API

connect

Usage:

const ContainerComponent = connect(
state= > ({name:state.name}), // connect The first input parameter is a function that takes the state parameter and returns the value as the state passed to the UI component
dispatch= > ({
    increment: (data) = > dispatch(createIncrementAction(data))
    decrement:(data) = > dispatch(createDecrementAction(data))
}) // connect The second input can also be a function, called dispatch, that returns a value passed to the UI component as a method of operation state
)(UIComponent)

/ / attention! The second parameter can be reduced to the following format
const ContainerComponent = connect(
state= > ({name:state.name}),
{
    increment: createIncrementAction,
    decrement: createDecrementAction
} // The second argument can also be an object, with key being the exposed method name and value being action. This is the optimization the API provides for us
)(UIComponent)

// Use the UI component
this.props.increment(1);
<div>{this.props.name}</div>

// If you want to use provider, you need to pass it to store.
<ContainerComponent store={store}>
Copy the code

Function: Generates container components

Provider

Used to make all descendant components receive the Store

// index.js
import store from '/redux/store'
import {Provider} from 'react-redux'

ReactDOM.render(
    <Provider>
        <App/>
    </Provider>.document.getElementById('root'))Copy the code
CombineReducers (API on Redux)
import {createStore, combinerReducers} from redux
const allReducer = combinerReducers({
    count: reducerOne,
    person: reducerTwo
})
export default createStore(allReducer)
Copy the code
Use the React-Redux developer tools

1. Redux-devtools-extension 2.

// store.js
import  {composeWithDevTools} from 'redux-devtools-extension export defaule createStore(allReducer, composeWithDevTools())Copy the code

Supplementary document

setState

SetState changes state asynchronously. The second argument to setState is a callback that is executed after state is modified. The first argument can be in two formats, an object or a function. The function accepts two arguments, state and props

lazyLoad

Lazy loading is not applicable. As a result, the project directly loads all routing components. If the network speed is slow or the project is large, the user experience is poor. Use of lazy loading

Suspense // Introduce lazy and Suspense
import React, { Component, lazy, Suspense } from "react";
// Wrap the introduction of components with lazy
const About = lazy(() = > import("./About"));
const Home = lazy(() = > import("./Home"));
Wrap all routes in Suspense and provide them with the components shown in load
<Suspense fallback={<h1>1111</h1>} ><Route path="/about" component={About} />
    <Route path="/home" component={Home} />
</Suspense>
Copy the code

Hooks

1, the state Hook
Const [XXX, setXxx] = react. useState(initValue) const [XXX, setXxx] = react. useState(initValue) An array containing two elements, 0 for the state and 1 for the function that updates the state value. (4) Two uses of setXxx setXxx (newValue): the argument is the new state value. SetXxx (value => newValue) : the parameter is a function that receives the original state and returns the new stateCopy the code
2, the Effect of hooks
useEffect(() = > {
    // You can do anything
    console.log(1111);
    // Clear the function
    return () = > {
        // Called when the component is uninstalled, and immediately after each effect is triggered}}, [])// If the second argument is not passed, it is called at initialization and any updates, passing an empty array is called only at initialization, passing some states is called only when those states change.
Copy the code
3, Ref Hook
Const myRef = react.useref (); <input ref={myRef} type="text">Copy the code

Fragment

<Fragment></Fragment>// Will not be rendered as tags, and supports keys<></>// Will not be rendered as a label, does not support keyCopy the code

Context (to revisit the document)

Context is used to transfer functions of multiple components. Context can be used to transfer parameters at deeper levels.

// context.js
// Create the context first, passing in the initial value in parentheses. Can be defined separately outside, and then the individual components are introduced.
const MyContext = React.createContext(init);
export default MyContext

/ / A component
import MyContxt from './context'
const {Provider} = MyContext;
render() {
  return (
    // Wrap the Provider in the outermost layer that needs to import data, and pass the data through value. B and all components under B can get value
    <Provider value={userName: 'xxx'} >
        <B/>
    </Provider>)}/ / B component
// Assuming that component B does not need to use the data in the context, it does not need to do anything.render() {
    return <C/>
}

/ / C components
/ / into the context
import MyContext from './contex'; .// Define the contextType attribute on the class, which allows you to use 'this.context' to get the value of the context
static contextType = MyContext; 

render() {
    return <div>{this.context.userName}</div>
}
Copy the code

We can also change the values in the context dynamically by passing functions

/ / A component. state ={userName: 'xxx'
}
changeUserName = () = > {
    this.setState({
        userName: 'www'})}render() {
  return (
    <Provider value={userName: this.state.userName.changeUserName: this.changeUserName} >
        <B/>
    </Provider>)}/ / C components.render() {
    return (
        <div>{this.context.userName}</div>
        <button onClick={this.context.changeUserName}>Modify the user</button>)}Copy the code

If it is a functional component and cannot declare contextType in the class, we can use context.consumer

import MyContext from "./Context";
const{ Consumer } = MyContext; .return (
    // Consumer wraps a function that takes in the value passed by context
    <Consumer>
      {value => {
        return (
          <div>{value.username}, age: {value.userage}</div>)}}</Consumer>
)
Copy the code

Purecomponent

RenderProps implementation scheme

ChildrenProps, problem: B can’t get the data in childrenProps

     <A>
         <B></B>
     </A>
     
    class A extend Component {
        render () {
            <div>
                {this.props.children}
            </div>}}Copy the code

2, render props: Pass A function property (custom name) to A. Commonly called render, this function returns a component

    <A render={(data) = > <B data={data}/>} / >class A extend Component {
        render () {
            <div>// Call the render method passed in within the A component and pass the parameters. {this.props. Render (data)}} {this.props.</div>}}Copy the code