Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React: Why component's constructor is called only once?

Tags:

reactjs

In the following example, when Item 2 is clicked, Second 1 is shown instead of Second 2. Why? How would you fix that?


var guid = 0;

class Content extends React.Component {
  constructor() {
    guid += 1;
    this.id = guid;
    console.log('ctor', this.id); // called only once with 1
  }
  render() {
    return (
      <div className="content">
        {this.props.title} - {this.id}
      </div>
    );
  }
}

class MyApp extends React.Component {
  constructor() {
    this.items = ['Item 1', 'Item 2'];
    this.state = {
      activeItem: this.items[0]
    };
  }
  onItemClick(item) {
    this.setState({
      activeItem: item
    });
  }
  renderMenu() {
    return (
      <div className="menu">
        <div onClick={this.onItemClick.bind(this, 'Item 1')}>Item 1</div>
        <div onClick={this.onItemClick.bind(this, 'Item 2')}>Item 2</div>
      </div>
    );
  }
  renderContent() {
    if (this.state.activeItem === 'Item 1') {
      return (
        <Content title="First" />
      );
    } else {
      return (
        <Content title="Second" />
      );
    }
  }
  render() {
    return (
      <div>
        {this.renderMenu()}
        {this.renderContent()}
      </div>
    );
  }
}
like image 281
Misha Moroshko Avatar asked Sep 25 '22 16:09

Misha Moroshko


People also ask

How many times constructor is called in React?

A constructor is called every time the component is mounted, not only once.

How many times ComponentwillMount is called?

javascript - ComponentwillMount is called twice - Stack Overflow.

Is constructor called everytime?

Answer: Every time an object is created using new() keyword, at least one constructor is called. It calls a default constructor. Note: It is called constructor because it constructs the values at the time of object creation.

How many times is componentDidMount called in a component's lifecycle?

2. How many times componentDidMount is called? React components call componentDidMount only once by default. You can run the component multiple times if you delete the component or change the props or state.


1 Answers

React's reconciliation algorithm assumes that without any information to the contrary, if a custom component appears in the same place on subsequent renders, it's the same component as before, so reuses the previous instance rather than creating a new one.

If you were to implement componentWillReceiveProps(nextProps), you would see that getting called instead.

Different Node Types

It is very unlikely that a <Header> element is going to generate a DOM that is going to look like what a <Content> would generate. Instead of spending time trying to match those two structures, React just re-builds the tree from scratch.

As a corollary, if there is a <Header> element at the same position in two consecutive renders, you would expect to see a very similar structure and it is worth exploring it.

Custom Components

We decided that the two custom components are the same. Since components are stateful, we cannot just use the new component and call it a day. React takes all the attributes from the new component and calls component[Will/Did]ReceiveProps() on the previous one.

The previous component is now operational. Its render() method is called and the diff algorithm restarts with the new result and the previous result.

If you give each component a unique key prop, React can use the key change to infer that the component has actually been substituted and will create a new one from scratch, giving it the full component lifecycle.


  renderContent() {
    if (this.state.activeItem === 'Item 1') {
      return (
        <Content title="First" key="first" />
      );
    } else {
      return (
        <Content title="Second" key="second" />
      );
    }
  }
like image 118
Jonny Buchanan Avatar answered Oct 09 '22 19:10

Jonny Buchanan