DEV Community

Cover image for Visualizing React hooks' lazy initial state
Ricardo Busquet
Ricardo Busquet

Posted on • Edited on • Originally published at ricardobusquet.com

Visualizing React hooks' lazy initial state

Most examples of React hook's lazy initial state uses inline arrow functions to showcase the usage:

function App() {
  const [state, setState] = React.useState(() => expensiveComputation());
  // ...
}
Enter fullscreen mode Exit fullscreen mode

Paired with the idea that whatever you pass to React.useState is the initial value of the state, it can be hard to grasp the difference from the example below:

function App() {
  const [state, setState] = React useState(
    expensiveComputation(),
  );
  // ...
}
Enter fullscreen mode Exit fullscreen mode

For me, it helps to visualize the difference if you assign what’s inside the parentheses to a constant.

function App() {
  const initialState = 0;
  const [state, setState] = React.useState(initialState);
  // ...
}
Enter fullscreen mode Exit fullscreen mode

Everytime App re-renders, the function App will re-run completely. This means 0 is set to initialState in every render. Now let's do the same with the expensive computation example:

function App() {
  const initialState = expensiveComputation();
  const [state, setState] = React.useState(initialState);
  // ...
}
Enter fullscreen mode Exit fullscreen mode

It's pretty clear now that the expensive function is called every time the component renders. React.useState is just ignoring its result in subsequent renders. And that's what you want to avoid when passing a function to the hook.

React.useState implementation detects if you're passing a function and makes sure to call it once for the component's lifetime.

The tradeoff now is that you're creating a new function for every render. That's acceptable if the computation takes longer or is more complex than instantiating an inline function. If that's not the case (for example, when setting a constant like 0 in the first example), go with passing the value directly to React.useState.

Photo by Presley Roozenburg on Unsplash

Top comments (0)