Functional React Components life cycle

74 views Asked by At

Considering the code:

function Comp5 () {
  const [count, setCount] = useState(0)
  const valRef = useRef(0)
  useEffect(() => {
    setCount(prevCount => prevCount + 1)
  }, [])
  valRef.current += 1
  console.log('valRef_Current', valRef.current)
  return <div>Comp5</div>
}



function App () {
  return (
    <div>
      <Comp5 />
    </div>
  )
}

What´s your console output? I think that it should be: valRef_Current 1 valRef_Current 2 valRef_Current 3 valRef_Current 4

But the real output is: valRef_Current 1 valRef_Current 1 valRef_Current 2 valRef_Current 3

Can anyone help me understand why?

thanks in advance

2

There are 2 answers

0
lawrence-witt On BEST ANSWER

The cause of your real output is React Strict Mode, a development tool for highlighting deprecated and unsafe methods. It is automatically included with new create-react-app projects, and on codesandbox, which is where I was able to replicate your behaviour. It will cause double renders in the process of doing its job, but will not be included when you create a production build. You can usually find it wrapped around the top level <App/> in index.js.

The expected behaviour is actually:

valRef_Current 1

valRef_Current 2

The component mounts, increments valRef and logs it. The useEffect then sets the state with a new value which causes one additional render. valRef is incremented again and its value is logged. You can observe the behaviour in this snippet:

function Comp5 () {
  const [count, setCount] = React.useState(0);
  const valRef = React.useRef(0);

  React.useEffect(() => {
    setCount(prevCount => prevCount + 1)
  }, []);

  valRef.current += 1
  console.log('valRef_Current', valRef.current);

  return <div>Comp5</div>
};



function App () {
  return (
    <div>
      <Comp5 />
    </div>
  )
};

ReactDOM.render(<App/>, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="root"></div>

0
Sifat Haque On

I think your component is rendering twice initially because of <React.StrictMode>

  <React.StrictMode>
    <App />
  </React.StrictMode>,

This will only happen on development environment. You can remove the <React.StrictMode> to see the actual renders. And on that case your output will be.

valRef_Current 1
valRef_Current 2

You can check this blog post for details