nonopolarity
nonopolarity

Reputation: 151126

Why is the React app printing out a render count of jumping by 2?

This may be a somewhat advanced question for ReactJS.

I tried to analyze how many times a function component is called, and the number of re-rendering is done. So I have the React app print out the count in the dev console:

import { useState } from "react";

let renderCount = 0;

export default function App() {
  console.log("renderCount", ++renderCount);

  const [count, setCount] = useState(0);

  function handleClick() {
    setCount(count + 1);
  }

  return (
    <div className="App">
      <div>{count}</div>
      <button onClick={handleClick}>Click</button>
    </div>
  );
}

Demo: https://codesandbox.io/s/frosty-http-w3kzr?file=/src/App.js

I have seen it jump up by 2 before and kind of ignored it, but I noticed my increment is on the same line of my console.log, so it is very strange that incremented twice but printed out once.

Just to double check, I used a useRef()

const anotherCount = useRef(0);

and it "well behaved" for 1 time (increment by 1 for 1 click), and then it also incremented 2 every time:

Demo: https://codesandbox.io/s/vibrant-nobel-88w34?file=/src/App.js

So I suspected the console.log is morphed by React, and so I used window.console.log, and it was the same result, and so I added something that would check for the morphing:

  const consoleLogFn = useRef(window.console.log);
  if (consoleLogFn.current !== window.console.log) {
    s += "MORPHING ";
  }
  console.log("s is", s);

Demo: https://codesandbox.io/s/focused-cartwright-x9cs2?file=/src/App.js

So it printed out "MORPHING " and it does look like console.log is morphed.

So the question is:

  1. Why is renderCount incrementing by 2 every time, but the ref one has a "delayed start"?

  2. So I think the morphing is done by ReactJS so that we don't see something printed out twice, but the code is still executed, so that any "side effect" is not skipped?

  3. So I take it that the renderCount is accurate: a 1 means doing the rendering one time, a 2 means rendering two times? (of course, if the virtual DOM doesn't have any diff with the previous virtual DOM, there is no "heavy" actually DOM altering, but if the app has costly rendering to produce the same virtual DOM, it can still be costly for CPU time).

Upvotes: 1

Views: 212

Answers (1)

Netanel Vaknin
Netanel Vaknin

Reputation: 1153

removing <StrictMode> component from your index.js file will fix the problem.

Please read more about StrictMode over here .

Good luck!

Upvotes: 1

Related Questions