<div id="app"></div>
<div id="innerLifeCycleDiv" style="white-space: pre-wrap; margin: 20px; padding: 20px; border: 1px solid #111"></div>
const _nd = document.getElementById('innerLifeCycleDiv');
const _innerLifeCycle = [];
const innerLifeCycle = new Proxy(_innerLifeCycle, {
  get: function (target, propKey) {
    if (propKey === 'push' || propKey === 'shift') {
      return (...args) => {
        const x = target[propKey](args);
        _nd.innerHTML = target.join('\n');
        return x;
      }
    } else {
      return target[propKey];
    }
  }
});

class Inner extends React.Component {
  constructor() {
    super();
    innerLifeCycle.push("constructor()");
    this.state = {
      count: 0,
    };
    
    this.updateCount = this.updateCount.bind(this);
    this.fnForceUpdate = this.fnForceUpdate.bind(this);
  }

  static getDerivedStateFromProps() {
    innerLifeCycle.push("getDerivedStateFromProps()");
  }

  componentDidMount() {
    innerLifeCycle.push("componentDidMount()");
  }

  shouldComponentUpdate() {
    innerLifeCycle.push("shouldComponentUpdate()");
    return true;
  }

  getSnapshotBeforeUpdate() {
    innerLifeCycle.push("getSnapshotBeforeUpdate()");
  }

  componentDidUpdate() {
    innerLifeCycle.push("componentDidUpdate()");
  }

  componentWillUnmount() {
    innerLifeCycle.push("componentWillUnmount()");
  }
  
  updateCount () {
    while (innerLifeCycle.shift());
    this.setState((state, prop) => ({
      count: state.count + 1,
    }));
  }
  
  fnForceUpdate () {
    while (innerLifeCycle.shift());
    this.forceUpdate();
  }

  render() {
    innerLifeCycle.push("render()");
    return (
      <div>
        <span>Inner Controller: </span>
        <button onClick={this.updateCount}>Update Inner State</button>
        <button onClick={this.fnForceUpdate}>Force Update</button>
      </div>
    );
  }
}

class App extends React.Component {
  constructor() {
    super();
    this.state = {
      isInnerMount: true,
      outterCount: 0,
    };
    
    this.switchMount = this.switchMount.bind(this);
    this.updateInnerProps = this.updateInnerProps.bind(this);
  }
  
  switchMount () {
    while (innerLifeCycle.shift());
    this.setState((state, props) => ({
      isInnerMount: !state.isInnerMount,
    }));
  }
  
  updateInnerProps () {
    while (innerLifeCycle.shift());
    this.setState((state, props) => ({
      outterCount: state.outterCount + 1,
    }));
  }

  render() {
    return (
      <div>
        <p>The following content shows the lifeCycle of component 'Inner'.</p>
        <span>App Controller: </span>
        <button onClick={this.switchMount}>Switch Mount</button>
        <button onClick={this.updateInnerProps}>Update Inner Props</button>
        {this.state.isInnerMount && <Inner outterCount={this.state.outterCount} />}
      </div>
    );
  }
}

ReactDOM.render(<App />, document.getElementById("app"));
View Compiled

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/react/16.13.1/umd/react.production.min.js
  2. https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.13.1/umd/react-dom.production.min.js