0

I am trying to gain a better understanding of the React component life cycle. I am trying to print to the console messages related to the life cycle of React components. In the component I show below I am using console.log 3 times. However, 2 of them are printed twice in the console. I am using chrome. This is what gets printed to the console.

Menu Component constructor is invoked
Menu Component constructor is invoked
Menu Componen render is invoked
Menu Componen render is invoked
Menu Component componentDidMount is invoked

Why the double printing of two out of the three console.log messages except for the componentDidMount? Whid does the console.log for componentDidMount get printed only once. Below is how the entire code for the component:

import React, { Component } from 'react';
import { Card, CardImage, CardImgOverlay, CardText, CardBody, CardTitle, CardImg } from 'reactstrap';

class Menu extends Component {

    constructor(props) {
        super(props);

        this.state = {
            selectedDish: null
        }
        console.log('Menu Component constructor is invoked');
    }

    componentDidMount() {
        console.log('Menu Component componentDidMount is invoked');
    }

    onDishSelect(dish) {
        this.setState({ selectedDish: dish});
    }

    renderDish(dish) {
        if (dish != null) {
            return(
                <Card>
                    <CardImg width="100%" src={dish.image} alt={dish.name} />
                    <CardBody>
                        <CardTitle>{dish.name}</CardTitle>
                        <CardText>{dish.description}</CardText>
                    </CardBody>
                </Card>
            );
        } else {
            return(
                <div></div>
            );
        }
    }

    render() {

        const menu =  this.props.dishes.map((dish) => {
            return (
                <div key={dish.id} className="col-12 col-md-5 m-1">
                    <Card onClick={() => this.onDishSelect(dish)}>
                        <CardImg width="100%" src={dish.image} alt={dish.name} />
                        <CardImgOverlay>
                            <CardTitle>{dish.name}</CardTitle>
                        </CardImgOverlay>
                    </Card>
                </div>
            );
        });

        console.log('Menu Componen render is invoked');

        return (
            <div className="container">
                <div className="row">
                    {menu}
                </div>
                <div className="row">
                    {this.renderDish(this.state.selectedDish)}
                </div>
            </div>
        );
    }
}

export default Menu;
larry8989
  • 339
  • 1
  • 11

1 Answers1

0

With the introduction of React.StrictMode which I assume you would have already had with your react app, react has provided a way to detect unexpected sideeffects by invoking the render phase lifecycles twice.

According to the docs:

Render phase lifecycles include the following class component methods:

- constructor
- componentWillMount (or UNSAFE_componentWillMount)
- componentWillReceiveProps (or UNSAFE_componentWillReceiveProps)
- componentWillUpdate (or UNSAFE_componentWillUpdate)
- getDerivedStateFromProps
- shouldComponentUpdate
- render
- setState updater functions (the first argument)

However componentDidMount is not a render phase lifecycle but a commit phase lifecyle and hence its only invoked once.

Shubham Khatri
  • 270,417
  • 55
  • 406
  • 400