Why is console.log logging twice in react js?

Viewed 13765

I have started learning React and I am not able to understand why is the console.log logging twice. Below is my code and when I inspect it in chrome it shows the word 'random-text' twice instead of once.

import React, { Component } from "react";

class Counter extends Component {
  state = {
    count: 0

  };



  render() {
    console.log('random-text');

    return (
      <div>
        <span className={this.getBaadgeClasses()}>{this.formatCount()}</span>
        <button
          onClick={this.handleIncrement}
          className="btn btn-success m-2"
        >
          Increment
        </button>

        {/* <ul>
          {this.state.tags.map((tag) => (
            <li key={tag}>{tag}</li>
          ))}
        </ul> */}
      </div>
    );
  }

  getBaadgeClasses() {
    let classes = "badge m-2 badge-";
    classes += this.state.count === 0 ? "warning" : "primary";
    return classes;
  }

  formatCount() {
    const { count } = this.state;
    return count === 0 ? "Zero" : count;
  }

  handleIncrement = () => {
    this.setState({count: this.state.count + 1})
  }

}

export default Counter;
2 Answers

The render function is a lifecycle function, called during the "render phase"

enter image description here

react lifecycle methods diagram

Notice that these functions are pure functions, and can be paused, aborted, or restarted by React. This means react can call render almost any number of times to reconcile the virtualDOM with the actual DOM.

Detecting unexpected side effects

Strict mode can’t automatically detect side effects for you, but it can help you spot them by making them a little more deterministic. This is done by intentionally double-invoking the following functions:

  • Class component constructor, render, and shouldComponentUpdate methods
  • Class component static getDerivedStateFromProps method
  • Function component bodies
  • State updater functions (the first argument to setState)
  • Functions passed to useState, useMemo, or useReducer

Note:

This only applies to development mode. Lifecycles will not be double-invoked in production mode.

If you truly want a one-to-one console log when the component updates use one of the other lifecycle functions, like componentDidUpdate to do the side-effect of logging details.

class Counter extends Component {
  state = {
    count: 0
  };

  componentDidUpdate() {
    console.log("random-text");
  }

  render() {
    return (
      <div>
        <span className={this.getBaadgeClasses()}>{this.formatCount()}</span>
        <button onClick={this.handleIncrement} className="btn btn-success m-2">
          Increment
        </button>

        {/* <ul>
          {this.state.tags.map((tag) => (
            <li key={tag}>{tag}</li>
          ))}
        </ul> */}
      </div>
    );
  }

  getBaadgeClasses() {
    let classes = "badge m-2 badge-";
    classes += this.state.count === 0 ? "warning" : "primary";
    return classes;
  }

  formatCount() {
    const { count } = this.state;
    return count === 0 ? "Zero" : count;
  }

  handleIncrement = () => {
    this.setState({ count: this.state.count + 1 });
  };
}

Edit use lifecycle function to log

When you create this project, this project enables Strict Mode automatically. So, To solve this problem firstly open index.js file in your project and then disable strict mode.

Step 1: when you open index.js file then you will see something like this,

root.render(
   <React.StrictMode>
    <App />
   </React.StrictMode>
);

Step2: Now do this,

root.render(
  // <React.StrictMode>
    <App />
  // </React.StrictMode>
);

I hope this will help you. Thank You

Related