Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

React re-execute inner useState function after each re-render

Edit

Okay my bad, I guess the response is simple. It’s a javascript matter. I am not passing a function to useState but actually I am re-executing it everytime. So yeah what I am seeing is normal.

I will let my question here anyway.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel


A codesandbox example will follow.

Question :

Could someone please explain to me why React re-execute the inner function in a useState (or useRef) despite the returned value will be completely ignored (except the first execution) ? Is this the expected behaviour of useState ?

Explanation :

I mean why I see this console log here after each re-render

const [count, setCount] = React.useState((function(){
  console.log('Executed !');
  return 5;
})())

I used to think this inner function (or values) is the equivalent of a Class Parameters or Component Constructor but it’s obviously not the case.

Returning a simple value does the job of course : React.useState(5).

But imagine using a third-party class which works with static values at some point or you simply don’t want to re-execute it over and over again after each re-render ?

A possible fix for this is using useEffect with an empty dependency. (The equivalent of componentDidMount)

But I am asking about the purpose of this execution ?

let count = 0; // Number of component renders

const Test = (props) => {
  const [innerCount, setCount] = React.useState((function(){})(
    console.log('Executed !'); // Executed after each re-render
    count = count + 1;
    return count;
  ));
  return innerCount; // Will be always 1 !
}

Why the anonymous function will be executed if the returned value is always 1 = the first returned value ?! What’s the purpose of this execution ?

This is an example on CodeSandbox

>Solution :

This isn’t React-specific behaviour, it’s just what Javascript – and almost every mainstream programming language – does.

Before calling a function, it has to evaluate its arguments in order to know what to pass in.

Yes, it so happens that React.useState is a function that often "ignores" its argument. (I’m not familiar with precisely how it’s implemented – clearly it isn’t as simple as that as it does need to know when it’s the first time it’s being executed in that particular component instance, because in that case that value is used and returned.) But the browser Javascript engine can’t possibly know that or optimise it away.

To prove this isn’t anything to do with React, I can do this:

function ignoresArgument(x) {
  return 1;
}

for (let i = 0; i < 20; i++) {
  ignoresArgument(
    (function(y) {
      console.log("I don't need to be executed, but Javascript doesn't know that so I will be executed 20 times");
      return 2;
    })(1)
  );
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading