2

I came across this when I was experimenting with react components. I have a component:

window.renderCount=1;

export function Soundscapes() {

    const soundscape = useSelector((s) => s.tasks.soundscape);
    const dispatch = useDispatch();
   
    const [soundscapeAudioElement, setSoundscapeAudioElement] = useState(undefined);
    useEffect(()=>{
        console.log('state just changed to: ', soundscapeAudioElement )
    },[soundscapeAudioElement])

    
    console.log(window.renderCount);
    window.renderCount=window.renderCount+1;

    return (<SomeJSXUnrelatedToQuestion/>)
}

In the console, I noticed that the logs are 1,3,5,7,9 on subsequent re-rendering. I expected it to print renderCount everytime it is incremented by 1 on the screen like 1,2,3,4,5, each time the component got rendered to screen. But it seems to be incrementing it, but not printing it to console everytime.

Am I missing something here?

Ajeet Shah
  • 18,551
  • 8
  • 57
  • 87
pg07
  • 137
  • 2
  • 11
  • the code snippet is part of a larger project and the component shown is nested into many Higher level components. I am not sure if i can reproduce the issue in a sandbox. my main goal of asking the question was to clarify the issue that the logic for printing(console.log) and incrementing are next to each other but incrementing logic is executed more times than console.log which is imo weird. i was wondering, if i am missing some knowledge about lifecycle of react component. – pg07 Feb 14 '21 at 18:32
  • Oh I think, using `window.something` is the problem. Maybe you used `window.renderCount` in other components too. So, here is a suggestion: use `useRef` to do render counting for each component if you are doing that. `window` is a global browser object which is shared with all of your components. – Ajeet Shah Feb 14 '21 at 18:38
  • no that's not the issue. i used a local variable (not attached to window) and replicated the same scenario. it does not seem to be related to "attaching to window" , of that I'm sure. – pg07 Feb 14 '21 at 19:11

1 Answers1

10

You probably have StrictMode on. StrictMode will intentionally double invoke "render" and some other lifecycle methods to detect side-effects. Strict mode checks are run in development mode only; they do not impact the production build. Check the below snippet. Also, note that I have used React development CDNs.

function App() {
    const [foo, setFoo] = React.useState(false)
    const counter = React.useRef(0)
    console.log(counter.current++)
    return (
      <button onClick={() => setFoo(f => !f)} > Click </button>
     )
}

ReactDOM.render(<React.StrictMode><App /></React.StrictMode>, document.getElementById('mydiv'))
<script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
<body>
<div id="mydiv"></div>
</body>
Ajeet Shah
  • 18,551
  • 8
  • 57
  • 87
  • thanks a lot mate. this seems to be the case. i would really appreciate if you could check out this question which was the real idea behind posting this `related` question. - https://stackoverflow.com/questions/66196469/audio-element-is-changing-in-react-state-by-itself – pg07 Feb 14 '21 at 20:06