3

I'm doing something like this:

function App() {

  const [state1, setState1] = useState([1,1,1,1,1,1]);
  const [state2, setState2] = useState(MyFunction());

  return (
    <div className="App">
    <button onClick={() => setState1([1,2,3,4,5,6])}>test</button>
    </div>
  );
}

const MyFunction= () => {
  alert("MyFunction");
  return 5;
}

The strange thing is that the line alert("MyFunction"); is triggered 2 times on load and 2 times on every click on test button.

I'm very new to React.js and I don't understand this behavior.

8
  • 1
    Are you by chance using strict mode? Ie, do you render a <React.StrictMode> near the top of your app? Commented Dec 8, 2021 at 20:48
  • 1
    In strict mode, components are deliberately double-rendered to help identify misuse of the lifecycle hooks. So while normally you'd get one render when the component mounts, and then one every time you set state, you'll get two instead in strict mode. This only occurs in development builds of your app, not production builds. Commented Dec 8, 2021 at 20:51
  • 1
    To set an initial state value based on a function call, use useEffect and pass an empty dependency array (which means the passed function will only run once, and you can do basic "on mount" stuff inside): codesandbox.io/s/angry-glitter-gqf99?file=/src/App.js Commented Dec 8, 2021 at 20:53
  • 1
    Changing state causes the function to rerender. When it rerenders, the code runs from the top of the App function to the bottom, and one of the things you do in there is call MyFunction(). you then pass the return value of MyFunction() into useState. This only matters on the first render, but with the way you've written it, it happens on every render. Commented Dec 8, 2021 at 20:58
  • 1
    When state changes, the component is re-rendered. This means the function runs again, which means const [state2, setState2] = useState(MyFunction()); runs again, which means the function in question runs again. Keep in mind that React is just JavaScript (granted, with some JSX magic added). Commented Dec 8, 2021 at 20:58

1 Answer 1

2

To answer your question:

how to calculate default value for react js state hook with a function?

useState allows a function as a 'initial state factory', like e.g.:

const [ state, setState ] = useState( function(){ return Math.random(); } );

So if you want to use your MyFunction as a factory, just use it this way:

const [ state2, setState2 ] = useState( MyFunction );

why is MyFunction called on every click ?

A React functional component is just a javascript function.

React decides when to call this function, which is basically whenever something changes. A call of some setState() is one reason why React will call the function of the functional component again (your App() function in this case).

But I suggest you consider the App() function to be called "whenever React wants to call it", or "all the time, again and again". Meaning you should not rely on when the function of the functional component is called, you should instead rely on the guarantees which React makes regarding when the state is up-to-date, specifically useEffect, useState, ...

MyFunction() is just a function call, which is inside the App() function call, so - of course - MyFunction() is called whenever App() is called (which is "again and again").

Why is the alert() called twice ?

The functional component is called 2 times in Strict Mode. This causes unexpected behavior only if you aren't using React as it is supposed to be used (which is something that just happens for React-beginners).

If you are using React in the intended way, you should not have to care about if the function is called once, twice or multiple times. The only thing that counts is what the state is.

See also e.g. React.Component class constructor runs once without console.log?

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.