2

I tried to track the number of times react component is rendered. However, it seems that the renderCounter gets incremented by 2 each time.

Why does this happen? I know it is a bad practice to use global variables, but I'm interested in the reason why this happens.

https://codesandbox.io/s/rendercounter-does-not-increment-correctly-093ok?file=/src/App.js

let renderCounter = 1;

function App() {
  const [i, inc] = useReducer((_) => _ + 1, 1);
  // render
  console.log(JSON.stringify(i), "th click");
  console.log("renderCounter", JSON.stringify(renderCounter));
  renderCounter = renderCounter + 1;
  return (
    <div>
      <button onClick={inc}>increment</button>
    </div>
  );
}

export default App;

Chuan
  • 429
  • 5
  • 16
  • @webdevdani But it doesn't hurt. Not sure why you mention it since it's not related to the question. When I do want to give the OP an unrelated tip, I make sure I mention that it has nothing to do with the problem. Consider deleting your comment so it doesn't detract the conversation – Ruan Mendes Nov 03 '20 at 21:53
  • 1
    It is good practice to JSON.stringify to obtain object snapshots because console.log can be async https://stackoverflow.com/questions/23392111/console-log-async-or-sync. @webdevdani – Chuan Nov 03 '20 at 21:56
  • 1
    Ah sorry, wish i could edit it! I'll delete. – webdevdani Nov 04 '20 at 21:32

1 Answers1

2

Yes, react render will be executed twice for you. Why - because your App wrapped in React.StrictMode component in index.js by default, why/what - there are plenty of resources covered it already, so let me just mention this one for example- https://medium.com/@andreasheissenberger/react-components-render-twice-any-way-to-fix-this-91cf23961625 But let me mention right away here - it will not happen if you build in production mode


UPDATE

Now it got really interesting, and i kind of disliked what React developers did. So all of above is valid, yeah, BUT as comment to this post suggested - why then we don't see console.log messages 2 times? WELL because of this - https://github.com/facebook/react/pull/18547 React developers simply disabled console log for second render time. So to see actual behaviour (which should log 2 times each time) you need to kind of play with console log, what i did - wrapped it in setTimeout:

setTimeout(() => console.log(...))
Nikita Chayka
  • 2,057
  • 8
  • 16
  • Weird, if you look at their example, the `console.log("renderCounter"` only happens once, so as much as it looks like the problem, I would expect two "renderCounter" to show up before you click the item – Ruan Mendes Nov 03 '20 at 23:32
  • Haa that's indeed actually interesting, but i suspect that console.log in sandbox somehow differs from standard one (yeah i understand that it is weird) but here is the catch - if you wrap console.log there in setTimeout for example - you would see it 2 times (as expected actually!) – Nikita Chayka Nov 03 '20 at 23:45
  • Removing the wrapping `` does fix the problem, so even though I don't understand why there aren't two logs per render, your answer is the correct one... – Ruan Mendes Nov 04 '20 at 00:02
  • @JuanMendes I understood now why we haven't seen console.log 2 times - see my update – Nikita Chayka Nov 04 '20 at 00:06