React learning the new life cycle of react

We have learned about the react life cycle before, but in version 16, the life cycle of the will class has been abolished. Although it can still be used, it needs to start with UNSAFE, which means it is UNSAFE.

  • There are three will in the life cycle of React16 abandonment:
    • componentWillMount
    • componentWillReceiveProps
    • componentWillUpdate

The reason for abandonment is that in the Fiber architecture of React16, the pause and restart operations can be performed in the middle, and the reconciliation process will execute the will cycle many times, which is no longer a single execution, losing its original meaning. In addition, multiple executions, if there is a setState or dom operation in the cycle, it will trigger multiple redraws, affect performance, and cause data disorder Therefore, it will start with UNSAFE.

New lifecycle

The life cycle of changes mainly occurs when updating

getDerivedStateFromProps

This lifecycle is used when getting data from the parent. It returns a combination of a new state and the current state of the page, as shown in the following example:

//  src/index.js
class Child extends React.Component {
  state = {
    count: 0
  }
  // Static method
  static getDerivedStateFromProps(nextProps, nextState) {
    return {
      count: nextProps.count * 2
    }
  }
  render() {
    return <div>{this.state.count}</div>;
  }
}
copy

It can be seen from the above that function execution should be performed before rendering, so as to ensure data synchronous rendering. It can be seen from the above life cycle diagram that props, state and forceupdate will trigger the life cycle, so we implement the following in the general method forceupdate:

// src/component.js
forceUpdate() {
    let oldRenderVdom = this.oldRenderVdom;
    let oldDOM = findDOM(oldRenderVdom);
    // Triggered before rendering
    if (this.constructor.getDerivedStateFromProps) {
      const newState = this.constructor.getDerivedStateFromProps(this.props, this.state)
      if (newState) {
        this.state = {
          ...this.state,
          ...newState
        }
      }
    }
    ...
copy

Why use static methods here? Maybe someone in componentWillReceiveProps will misuse setState, resulting in an endless loop, so it is changed to a static method

getSnapshotBeforeUpdate

Take a snapshot of the current dom structure before updating, and get the various states of the page before updating. For example, the scrollTop in your browser before rendering will change after updating, so you can remember the current state for calculation.

It is worth noting that the getSnapshotBeforeUpdate method can return an object, which can be obtained in the third parameter of componentDidUpdate.

Examples are as follows:

class ScrollList extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
      messages: []
    }
    this.container = React.createRef()
  }
  componentDidMount() {
    this.timer = setInterval(() => {
      this.addMessage()
    }, 1000)
  }
  componentWillUnmount() {
    clearInterval(this.timer)
  }
  addMessage = () => {
    this.setState({
      messages: [`${this.state.messages.length}`,...this.state.messages, ]
    })
  }
  // Return value to didupdate
  getSnapshotBeforeUpdate() {
    // Remember current scroll bar position
    return {
      prevScrollTop: this.container.current.scrollTop,
      prevScrollHeight: this.container.current.scrollHeight
    }
  }
  componentDidUpdate(prevProps, prevState, {prevScrollTop ,prevScrollHeight}) {
    this.container.current.scrollTop = prevScrollTop + (this.container.current.scrollHeight - prevScrollHeight)
  }
  render() {
    const style = {
      height: '100px',
      width: '200px',
      border: '1px solid red',
      overflow: 'auto'
    }
    return <div style={style} ref={this.container}>
      {this.state.messages.map(msg => {
        return <div key={msg}>{msg}</div>
      })}
    </div>
  }
}
copy

Since this method is also triggered before rendering, we also implement it before render in forceUpdate:

forceUpdate() {
    ...
    // Call before update
    const snapShot = this.getSnapshotBeforeUpdate()
    let newRenderVdom = this.render();
    ...
    if (this.componentDidUpdate) {
      this.componentDidUpdate(this.props, this.state, snapShot);// Third parameter
    }
  }
copy

The specific usage of this life cycle is based on your actual situation. The small examples in this article are only for your understanding.

There are not many concepts in this section. The main idea is to understand that react has proposed two new life cycles for fiber. In the next section, we will learn the concept of context in react.

Tags: Front-end React

Posted by lordtrini on Mon, 30 May 2022 11:52:15 +0530