React Lifecycle (old)

First to see figure

React component initialization phase:

Initialization phase: triggered by reactdom.render () — initial render

The first step in the constructor ()

Used to initialize the state of the property

  constructor() {
   super(a)console.log('constructor--count component constructor ');
   this.state = {
     count: 0.message: 'I want food'
   }
Copy the code

The second step componentWillMount ()

Component to be mounted phase (triggered before component is mounted)

  componentWillMount() {
    console.log('componentWillMount-- Count component to be mounted ');
  }
Copy the code

Step 3 – render()

Components are rendered on the page

  
  render() {
    console.log('Render --count component render');
    const { count } = this.state
    return (
      <div className="count">
        <h2>{count}</h2>
        <button onClick={this.add}>+ 1</button>
        <button onClick={this.force}>Force updates without changing any data state</button>
        <br />
        <div>
          <h3>I'm the Count component</h3>
          <button onClick={this.changeMessage}>Replace subcomponent information</button>
          <CountSon message={this.state.message} />
        </div>
      </div>)}Copy the code

The fourth step componentDidMount ()

After the component is mounted (after the component is mounted, it is executed only once)

  componentDidMount() {
    console.log('componentDidMount-- Count after component is mounted ');
  }
Copy the code

This hook is used to initialize the timer, send network requests, subscribe messages, etc.

React component update phase:

Triggered by the component’s internal this.setstate () or the parent’s render

The first step componentWillReceiveProps ()

The component will receive parameters

Called when the component receives a new property object. The first rendering is not triggered

When a parent component passes props to a child component, this function is triggered when the child component updates the data in the props.

  componentWillReceiveProps(props) {
    // Note that the first render does not count, only the second
    console.log('componentWillReceiveProps - the Count of child components', props);
  }
Copy the code

Step 2: shouldComponentUpdate()

Whether the component should be updated —- Control component updated “valve”

If it is true, it will go down as shown, if it is false, it will close the “valve” and cannot go down.

  shouldComponentUpdate() {
    console.log('shouldComponentUpdate-- Whether the count component should be updated ');
    return true* * * *}Copy the code

Step 3: componentWillUpdate()

Components to be updated

  componentWillUpdate() {
    console.log('componentWillUpdate-- Count component to update ');
  }
Copy the code

Step 4: render()

The component will be re-rendered with the new property object

Step 5: componentDidUpdate()

Triggered after the component has been updated

It accepts parameters (1. Props before the update, 2. State before the update, 3. Snapshot value, (mentioned in the new life cycle)

 componentDidUpdate(preProps, preState, snapShotValue) {
    console.log('componentDidUpdate-- Count component after update ', preProps, preState, snapShotValue);
  }
Copy the code

Component uninstallation phase

Triggered by ReactDOM. UnmountComponentAtNode ()

componentWillUnmount()

Emitted when a component is about to be uninstalled,

This hook is often used to do some finishing touches: turn off the timer, unsubscribe the message, etc.

(Old) life cycle code testing

import React, { Component } from 'react';

class Count extends Component {
  constructor() {
    super(a)console.log('constructor--count component constructor ');
    this.state = {
      count: 0.message: 'I want food'}}// The component will be mounted
  componentWillMount() {
    console.log('componentWillMount-- Count component to be mounted ');
  }

  // After the component is mounted
  componentDidMount() {
    console.log('componentDidMount-- Count after component is mounted ');
  }

  // Control module updated "valve"
  shouldComponentUpdate() {
    console.log('shouldComponentUpdate-- Whether the count component should be updated ');
    return true
  }

  // The component will be updated
  componentWillUpdate() {
    console.log('componentWillUpdate-- Count component to update ');
  }

  // After the component is updated
  componentDidUpdate() {
    console.log('componentDidUpdate-- Count component after update ');
  }

  
  render() {
    console.log('Render --count component render');
    const { count } = this.state
    return (
      <div className="count">
        <h2>{count}</h2>
        <button onClick={this.add}>+ 1</button>
        <button onClick={this.force}>Force updates without changing any data state</button>
        <br />
        <div>
          <h3>I'm the Count component</h3>
          <button onClick={this.changeMessage}>Replace subcomponent information</button>
          <CountSon message={this.state.message} />
        </div>
      </div>
    )
  }

  add = () = > {
    const { count } = this.state
    this.setState({
      count: count + 1
    })
  }

  force = () = > {
    this.forceUpdate()
  }

  changeMessage = () = > {
    // const { message } = this.state
    this.setState({
      message: "I want something to drink."}}})class CountSon extends Component {

  // The component will receive parameters
  componentWillReceiveProps(props) {
    // Note that the first render does not count, only the second
    console.log('componentWillReceiveProps - the Count of child components', props);
  }
  render() {
    return (
      <div>
        <h3>I'm a child of Count</h3>
        <span>I received a message from the parent component: {this.props. Message}</span>
      </div>)}}export default Count
Copy the code

Life cycle (New)

Look at the picture first

Compare the (old) life cycle

A comparison of the two pictures shows that the old version discarded three “will” and two “get”.

Waste:

  • componentWillMount
  • componentWillReceiveProps
  • componentWillUpdate

Feature:

  • getDerivedStateFromProps
  • getSnapshotbeforeUpdate

getDerivedStateFromProps

  1. It’s a static method, so I need to add astaticOtherwise, an error will be reported as follows:

Lifecycle method should be static: getDerivedStateFromProps

  1. Attribute object or NULL must be returned, otherwise an error is reported as follows:

A valid state object (or null) must be returned. You have returned undefined.

  1. You can pass parameters

Parameters: new property object (internal data state), old state object (external data props)

According to the official website, this hook is not recommended because derived states cause code redundancy and make components difficult to maintain. There’s not much to learn about it here.

getDerivedStateFromProps

Take a snapshot before updating

  1. You’ve got to have the hook and you’ve got to have the hook componentDidUpdate, you’ve got to work with it
  2. There must be a return value, which can be a value ornull
  getSnapshotBeforeUpdate() {
    console.log('getSnapshotBeforeUpdate--count')
    return 'Wangpf'
  }
  
  
  componentDidUpdate(preProps, preState, snapShotValue) {
    console.log('componentDidUpdate-- Count component after update ', preProps, preState, snapShotValue);
    // preProps External data before update
    // preState Specifies the value before the internal data update
    // snapShotValue is the value returned in the getDerivedStateFromProps hook function
  }
Copy the code

getSnapshotBeforeUpdate

Get the snapshot value before the update,

Here’s an example:

import React, { Component } from 'react';

import './News.css'

class News extends Component {

  state = {
    newsArr: []}componentDidMount() {
    setInterval(() = > {
      const { newsArr } = this.state
      const news = ` news${newsArr.length + 1}`

      this.setState({
        newsArr: [news, ...newsArr]
      })
    }, 1000)}getSnapshotBeforeUpdate() {
    return this.listHeight.scrollHeight
  }

  componentDidUpdate(preProps, preState, height) {
    // Subtract the updated height from the updated height and add = to the updated height
    // As long as possible at the bottom
    this.listHeight.scrollTop += this.listHeight.scrollHeight - height
  }

  render() {
    const { newsArr } = this.state
    return (
      <div className="list" ref={c= > this.listHeight = c}>
        {newsArr.map((item, index) => {
          return <div key={index} className='news'>{item}</div>
        })}
      </div>)}}export default News
Copy the code

The above example shows that I can use this hook to get the scroll height before the update, and then when it keeps scrolling, I want it to keep showing a certain position, rather than scrolling up to the top.

conclusion

Remember the more important hooks

  1. Render: called when initializing or updating a render
  2. ComponentDidMount: Called after a component is mounted, for example, to enable listening and send Ajax requests
  3. ComponentWillUnmount: Called when a component is about to be unmounted, for example, to do some finishing work, such as cleaning up timers, unsubscribe, etc.

Discarded hook

  1. componentWillMount
  2. componentWillReceiveProps
  3. componentWillUpdate

For the current version 17.0.1, there will be a warning and the prefix UNSAFE_ will be used, but it is not recommended because it is likely to be completely deprecated in the next 18 versions.