Class life cycle

Common and mandatory declaration cycles

  1. Constructor () // Initialize state

  2. **shouldComponentUpdate() // return true not to block updates/return false to block updates **

  3. Render () // Create the virtual DOM

  4. ****componentDidMount () // The component already appears on the page


  5. ******componentDidUpdate() // The component has been updated


  6. ********componentWillUnmount() // Component is about to be destroyed


Simple order of execution

First render: Constructor — Render — update UI — componentDidMount

Render again: props/setState() changed — shouldComponentUpdate — render?

(Y) Update UI — componentDidUpdate

(N)

** Destroy: **componentWillUnmount

* 1.constructor

Use: To initialize props, state(but setState cannot be called at this time), and write bind this

class B extends React.Component{
  constructor(props){    
     super(props)
     this.state = {
       n:1,
       m:2
     }
     this.onClick = this.onClick.bind(this)
  }
}
Copy the code

* 2.shouldComponentUpdate / React.pureComponent

Purpose: Return true not to block UI updates/false to block UI updates

Function: You can manually determine whether to update components and flexibly set the return value based on application scenarios to avoid unnecessary updates

import React form 'react' class App extends React.Component { constructor(props){ super(props) this.state = { n : 1 } } onClick = ()=>{ this.setState(state =>({ n: state.n + 1 })) this.setState(state =>({ n: state.n - 1 })) } shouldComponentUpdate(newProps,newState){ if(newState.n === this.state.n){ return false }else{ return Return (<div>App <div> {{n}} <button onClick={this.onClick}> + 1 </button> </div> </div> ) }}Copy the code

React provides a built-in function called PureComponent that allows you to determine whether the value of state has changed and not execute it if it has

import React form 'react' class App extends React.pureComponent { constructor(props){ super(props) this.state = { n : 1 } } onClick = ()=>{ this.setState(state =>({ n: state.n + 1 })) this.setState(state =>({ n: State.n-1}))} render(){console.log('render 1 ') return(<div>App <div> {{n}} <button onClick={this.onclick}> + 1 </button> </div> </div> ) }}Copy the code

The PureComponent compares each key of the new state to the old state and each key of the new props to the old props before render. If all keys have the same value, no render is performed; Render if any key value is different.

*3.render

Purpose: Used to display views with only one root element.

you can use if… Else,? The for loop cannot be used directly because it does not return a value and requires an array. Array.map is recommended

import React form 'react'class App extends React.Component { // ... Render (){// Single element return(<div>App<div>) // Multiple elements return(< react. Fragment> <div>11</div> <div>22</div> </ react. Fragment> // The React. The fragments can be abbreviated to < > < div > 11 < / div > < div > 22 < / div > < / a >) / / if... Else to write an if (...). { return ( ... ) }else{ return ( ... ) } return this.state.array.map(I => <div key={n}>{I}</div>)}}Copy the code

*4.componentDidMount()

This code relies on the DOM. For example, if you want to get the height and width of an element, you’d better write it here. AJAX requests to load data (official recommendation) execute this hook for first rendering

import React form 'react'
class App extends React.Component {   
 constructor(props){    
   super(props)
   this.state = { 
     width:undefined
    }
 }
componentDidMount(){
 const app = document.getElementById('app')
 const {width} = app.getBoundingClientReact()
 this.setState({width})
}
 render(){
  <div id="app"> APP </div>
 }
}
Copy the code

You can use React. CreateRef () to get elements for code optimization

Writing this way avoids the problem of conflicting ID declarations

class App extends React.Component{
appRef = undefined  constructor(props){    
     super(props)
    this.state = {
      width:undefined
    }
     this.appRef = React.createRef()
  }
componentDidMount(){
 const app = this.divRef.current
 const {width} = app.getBoundingClientReact()
 this.setState({width})
}
 render(){
  <div ref={this.appRef}> APP </div>
 }}
Copy the code

*5.componentDidUpdate(prevProps,prevState,snapshot)

PrevProps Props before the update,prevState State before the update

Purpose: Execute code after view update. AJAX requests can also be made here to update the data. Here setState may cause an infinite loop, except in if.

If shouldComponentUpdate returns false, this hook is not triggered because it is triggered when data is updated.

This hook is not executed for the first rendering (because there are no updates for the first load)

*6.componentWillUnmount

Purpose: Execute code when a component is about to be removed from the page and destroyed. Unmounted components are not mounted again. For example: If you’re listening for window scoll or timer or AJAX requests in componentDidMount, you should cancel at componentWillUnmount because the component has been destroyed and there’s no point listening