33

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;
3
  • I believe it's happening because you are calling getBaadgeClasses inside the render method, causing the component to re-render. Try removing this call and see what you get. Commented Jun 4, 2020 at 1:46
  • render method is in react's lifecycle. it'll be triggered when your component's props or state changed. Commented Jun 4, 2020 at 1:47
  • @DavidG I tried removing the getBadgeClasses inside the render method but it still logged twice.. Infact even with an empty div in render it logged twice.... Commented Jun 4, 2020 at 13:36

3 Answers 3

49

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

Sign up to request clarification or add additional context in comments.

4 Comments

Thank you very much for you answer. My doubt is will the react re-render even if there is no change in the state and props? Even with an empty div, the react is logging it twice. Why is this happening? I am a beginner so please excuse if the doubt sounds silly.
@HBK8396 I believe you are conflating the react framework invoking the render function (to compute a diff) with it committing anything to the DOM. Read the description of the "commit phase": "Can work with DOM, run side effects, schedule updates" and look at the lifecycle functions where you can do this. React traverses the entire virtualDOM tree and invokes render on every component, then it compares the output, then commits the diff. Even a component that renders static output (or null even) will have its render function invoked during reconciliation.
I understand it now sir. Everything is quite clear and thank you very much.
This answer is good, for more information this would help: reactjs.org/docs/strict-mode.html
37

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

3 Comments

Don't turn off strict mode. Strict Mode calls some of your functions twice in development for good reasons: react.dev/reference/react/…
@tim-phillips so we should get used to see 2 times in console? what if we call console.log function multiple times, then there will be mess.
Yes, and that’s ok
21

The React team is no longer silencing console methods during the double render in Strict Mode. If you do not want to remove Strict Mode, like @Florian Motteau mentions, then you can go into React Dev Tools and check the box Hide logs during second render in Strict Mode. See screenshot below:

enter image description here

Here is the quote from the React Team, as well as the link to the discussion on their Github page.

In Strict Mode, React double invokes render methods in order to flush out potential side effects. During the second render, React used to automatically silence console methods (ex. console.log() and console.warn()) to reduce the noise of multiple repeat logs. However, this ended up causing a lot of confusion for developers during debugging, so we are changing this behavior. - React Team

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.