import React from "react";

import ReactDOM from "react-dom";

// Define child components

class LifeCycle extends React.Component {

  constructor(props) {

    console.log("Into the constructor");

    super(props);

    // State can be initialized from constructor

    this.state = { text: "Text for child components" };

  }

  // when initialized/updated

  static getDerivedStateFromProps(props, state) {

    console.log("GetDerivedStateFromProps method execution");

    return {

      fatherText: props.text

    }

  }

  // called when initializing render

  componentDidMount() {

    console.log("ComponentDidMount method execution");

  }

  // called when the component is updated

  shouldComponentUpdate(prevProps, nextState) {

    console.log("ShouldComponentUpdate method executed");

    return true;

  }



  // called when the component is updated

  getSnapshotBeforeUpdate(prevProps, prevState) {

    console.log("GetSnapshotBeforeUpdate method executed");

    return "haha";

  }

  // called after component update

  componentDidUpdate(preProps, preState, valueFromSnapshot) {

    console.log("ComponentDidUpdate method execution");

    console.log("The value obtained from getSnapshotBeforeUpdate is", valueFromSnapshot);

  }

  // called when the component is uninstalled

  componentWillUnmount() {

    console.log("ComponentWillUnmount method execution for child component");

  }

  // Click the button to modify the method of the child component's text content

  changeText = () = > {

    this.setState({

      text: "Modified child component text"

    });

  };

  render() {

    console.log("Render method execution");

    return (

      <div className="container">

        <button onClick={this.changeText} className="changeText">Modify the child component text content</button>

        <p className="textContent">{this.state.text}</p>

        <p className="fatherContent">{this.props.text}</p>

      </div>); }}// Define the parent of the LifeCycle component

class LifeCycleContainer extends React.Component {



  // State can also be initialized as an attribute declaration like this

  state = {

    text: "Parent component text".hideChild: false

  };

  // Click the button to modify the parent component's text method

  changeText = () = > {

    this.setState({

      text: "Modified parent component text"

    });

  };

  // Click the button to hide (uninstall) the LifeCycle component's methods

  hideChild = () = > {

    this.setState({

      hideChild: true

    });

  };

  render() {

    return (

      <div className="fatherContainer">

        <button onClick={this.changeText} className="changeText">Modify the parent component text content</button>

        <button onClick={this.hideChild} className="hideChild">Hide child components</button>

        {this.state.hideChild ? null : <LifeCycle text={this.state.text} />}

      </div>

    );

  }

}

ReactDOM.render(<LifeCycleContainer />.document.getElementById("root"));

Copy the code

First of all, the React lifecycle is V16.3. After V16.4, there are some minor tweaks to the React lifecycle, which we can supplement later.

The Life cycle since React 16 can also be viewed in three phases: mount, update, and uninstall. In this process, I will compare the new life cycle methods of React 16 and some of the differences in the process compared to React 15.

Mounting Phase: Component Initialization Render (Mount)

In the example in the demo, the result printed in sequence is

Enter theconstructor
    getDerivedStateFromPropsMethods to performrenderMethods to performcomponentDidMountMethods to performCopy the code

The main difference between React 15 and React 16.3 is that getDerivedStateFromProps is added instead of componentWillMount.

GetDerivedStateFromProps is not a replacement for componentWillMount. In fact, componentWillMount is dangerous and not worth replacing. It should be scrapped

And getDerivedStateFromProps this API, its design is not trying to replace the original componentWillMount, attempting to replace componentWillReceiveProps, therefore it has and only one purpose: Use props to derive/update state

The React team ensured the lifecycle purity of getDerivedStateFromProps by directly constracting its uses at the naming level. So, if you use getDerivedStateFromProps for anything other than this purpose, it is, in principle, nonconforming.

It is worth mentioning that getDerivedStateFromProps in updating and mount two stages will be “out” (this is different from only appeared in the update phase componentWillReceiveProps). This is because the “derived state” appeal exists not only when props is updated, but also when props is initialized. React 16 provides more direct support for such appeals in the form of a specific lifecycle.

Know getDerivedStateFromProps

The new lifecycle method is called as follows:

static getDerivedStateFromProps(props, state)
Copy the code

At the usage level, you need to grasp three key points.

  1. GetDerivedStateFromProps is a static method

Static methods don’t depend on component instances, so you can’t access this inside the method

2. Second, this method can accept two parameters: props and state, which represent the props and state that the current component receives from the parent component, respectively

3. The third point, getDerivedStateFromProps, requires a return value in object format. If you do not specify the return value, React will most likely warn you

The return value of getDerivedStateFromProps is essential because React needs it to update (derive) the state of the component. So if you really don’t have a need to “derive state using props”, it’s best to just omit the lifecycle method, otherwise be sure to return null.

Note that the update action of the getDerivedStateFromProps method to state is not an “override” update, but rather a targeted update to a property

Updating stage: Component updates

React 15 / React 16.3

Note that React 16.4 “tweaks” the lifecycle process to the getDerivedStateFromProps lifecycle of the update process. Let’s take a look at the React 16.4+ lifecycle

React 16.4 mounts and unmounts the same as React 16.3.

1. In React 16.4, getDerivedStateFromProps is triggered by any component update process triggered by factors such as this.setState and forceUpdate.

2. In v 16.3, this lifecycle is triggered only by updates to the parent component.

So, why do we need getDerivedStateFromPropsne?

Behind the change of the first “according to” : Why do you want to replace with getDerivedStateFromProps componentWillReceiveProps?

1. GetDerivedStateFromProps is as an attempt to replace componentWillReceiveProps API and appear

2. GetDerivedStateFromProps cannot completely and componentWillReceiveProps draw equal-sign, its characteristic determines the us once in componentWillReceiveProps do, Cannot migrate to getDerivedStateFromProps 100%.

Let’s talk about these two points: 1. How about getDerivedStateFromProps instead of componentWillReceiveProps, GetDerivedStateFromProps can replace componentWillReceiveProps implementation based on props derived state.

2. As for why it cannot be completely and componentWillReceiveProps draw equal-sign, because it is too “focus”. The name getDerivedStateFromProps alone gives you an idea of this. In principle, it can do one thing and one thing only.

GetDerivedStateFromProps this API, relative to that of early componentWillReceiveProps, it is to do the subtraction “reasonable”. The determination to do this is illustrated by the fact that getDerivedStateFromProps is defined as a static method directly — the static method does not get the component instance’s this inside, This prevents you from doing anything in getDerivedStateFromProps like this.fetch(), irrational this.setState (the kind that causes an infinite loop) that might have side effects.

Therefore, behind the alternative componentWillReceiveProps getDerivedStateFromProps life cycle, React 16 enforces the best practice of using only getDerivedStateFromProps to map props to state. The purpose is to ensure that the behavior of life cycle functions is more controllable and predictable, and to help developers avoid unreasonable programming methods and life cycle abuse from the root; It also paves the way for a new Fiber architecture.

Missing componentWillUpdate with new getSnapshotBeforeUpdate

getSnapshotBeforeUpdate(prevProps, prevState) {
    // ...
}
Copy the code

This method is similar to getDerivedStateFromProps in that both emphasize “I need a return value.” The difference is that the return value of getSnapshotBeforeUpdate is given as the third parameter to componentDidUpdate. It is executed after the Render method and before the actual DOM is updated. In this phase, we can get the real DOM before and after the update and the state&props information before and after the update.

For this life cycle, it is necessary to focus on the communication process between it and componentDidUpdate. I gave a working example in the Demo that will help you visualize this process more concretely. The code is as follows:

// called when the component is updated

getSnapshotBeforeUpdate(prevProps, prevState) {

  console.log("GetSnapshotBeforeUpdate method executed");

  return "haha";

}


// called after component update

componentDidUpdate(prevProps, prevState, valueFromSnapshot) {

  console.log("ComponentDidUpdate method execution");

  console.log("The value obtained from getSnapshotBeforeUpdate is", valueFromSnapshot);
}

Copy the code

Now click on the “Modify child Component text content” button on the Demo screen to see the communication effect of the two life cycles

The getSnapshotBeforeUpdate method executes componentDidUpdate. The value obtained from getSnapshotBeforeUpdate is hahaCopy the code

It’s worth noting that this life cycle was designed to “cover all use cases for the obsolete componentWillUpdate, along with componentDidUpdate.” GetSnapshotBeforeUpdate needs to work with componentDidUpdate

Unmounting: Components are uninstalled

The life cycle of the uninstall phase is exactly the same as React 15