React Component Lifecycle

To my knowledge, when some events happen, react creates a virtual-DOM from scratch and compares it to the old virtual-DOM. If that is the case, when the render method is called, react should create components and return them to compare.

import React, { Component, Fragment } from 'react';
import ReactDOM from 'react-dom';
import './index.css';

class Demo extends Component {
  constructor(props) {
    console.log("constructor called");

    super(props);
    this.state = { dummy: 1, };
  }

  render = () => <button onClick={this.props.onChange}> button </button>;
}

class App extends Component {
  state = { num: 0, };

  onChange = () => {
    this.setState({ num: this.state.num+1 }); // mutate state to trigger a render
  }

  render() {
    console.log("rendered");
    return (
      <Fragment>
        <Demo onChange={this.onChange} />
      </Fragment>
    );
  }
}

ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  document.getElementById('root')
);

A quick console log reveals that the constructor is called the first time to mount the Demo component onto the page. However, subsequent renders do not create new Demo objects that are compared with the old virtual-DOM (since the constructor is not called).

At first, my theory was that when the constructor of Demo is called, it then calls the super constructor to check if a similar object with the same props already exists. But that was not the case as proven by moving console.log("constructor called"); before calling the parent constructor.

So my question is how does react know not to create another object?

Answer

The key here is that Demo is not unmounted. When you first render the app, it renders and mounts the Demo component and passes the onChange prop. But, when the callback is invoked from Demo it sets the state on App. Calling setState in App doesn’t unmount the Demo component, so there’s no need to mount it again. When the component is mounted initially is when the constructor runs. If you had a toggle on the App component that would only show the component within render if a certain condition is true, that would trigger the component to unmount.

Check out this codesandbox and play around a little: https://codesandbox.io/s/lifecycle-methods-vivn6?file=/src/Lifecycle.js.

Also, this is a cool diagram to get a sense of what’s happening: https://projects.wojtekmaj.pl/react-lifecycle-methods-diagram/ enter image description here

The main key is that the constructor runs when the component mounts. It will only run again if the component is unMounted from the DOM and then remounted later.

Leave a Reply

Your email address will not be published. Required fields are marked *