Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When does React create a new component instance?

I have a question about the constructor in React

Look at a example at https://codesandbox.io/s/lpr147kmyl

import React from "react";
import ReactDOM from "react-dom";

import "./styles.css";

class SimpleComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      number: props.number,
    }
    console.log('constructor', this.state.number)
  }
  render() {
    return (
      <div>
        {this.props.number}
      </div>
    )
  }
}

class App extends React.Component {
  constructor(props){
    super(props)
    this.state = {
      showFirstComponent: true,
    }

    setInterval(() => (
      this.setState(previousState => (
        { showFirstComponent: !previousState.showFirstComponent }
      ))
    ), 1000);
  }
  render(){
    let c1 = <SimpleComponent number="1" />
    let c2 = <SimpleComponent number="2" />
    return (
      <div className="App">
        <h1>
          {this.state.showFirstComponent ? c1 : c2}
        </h1>
      </div>
    );
  }
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

I checked the console log and saw only one log message. I thought there should be two log messages there as I create two instances of SimpleComponent :

let c1 = <SimpleComponent number="1" />
let c2 = <SimpleComponent number="2" />

My question is:

When does React create new a component instance and calls the component's constructor?

Thanks,

like image 972
Trung Avatar asked May 31 '26 20:05

Trung


2 Answers

According to the doc, constructor is only called before a component is mounted. If you add two more React Lifecycle functions to your code example: componentDidMount and componentWillUnmount, you'll see that the component only mounted once in the entire process, regardless of the times the state changes. If you then add shouldComponentUpdate to the component, you'll see that there is only one instance of SimpleComponent and the upper-level state change is shown as props change on SimpleComponent.

The reason why you don't see two instances mounting and unmounting here is that variables c1 and c2 are not instances of SimpleComponent as commonly and conveniently assumed. Instead, they are ReactElement, which is a description of the component instance.

The primary type in React is the ReactElement. It has four properties: type, props, key and ref. It has no methods and nothing on the prototype.

React (Virtual) DOM Terminology

Only when the element gets rendered, an instance of the component gets created and constructor and the Lifecycle functions get called at their respective time points.

So then why, as in your example, the element c2 never gets to be used to create a component? This goes back to how React decides when and what to update at a certain time (you can read more about it here:

When a component updates, the instance stays the same, so that state is maintained across renders.

In your example, when the App component renders c2 instead of c1, React sees that the new component element is the same as the old one so it reuses the component(i.e. only a single instance exists) and updates the props/states accordingly.

Here are some more readings that I find useful to understand this problem: https://developmentarc.gitbooks.io/react-indepth/content/life_cycle/birth_mounting_indepth.html

Mark Amery's answer to this question is also very helpful.

like image 186
Claire Lin Avatar answered Jun 04 '26 17:06

Claire Lin


If someone has landed here for react-native. Assigning different keys for different instances will create new instances instead of reusing the same instance.

   <MyComponent
       key={this.state.uniqueInstanceKey}
       myData={this.state.myData}/>
like image 21
DeltaCap019 Avatar answered Jun 04 '26 17:06

DeltaCap019