loading...

Lazy state initialization in functional components.

nibble0101 profile image Joseph Mawa ・2 min read

This brief post will focus on lazy state initialization using useState hook. If you don't know what useState hook is, you can read about it in my introductory article on useState hook Here.

If you want to initialize state in functional components, you can use useState hook. This hook takes the initial state as its argument and it returns an array of two entries. The argument passed is set as the initial state.

const[state, setState] = useState(1)

Sometimes instead of passing a primitive value, an object or an array as argument, you can also pass a function. The value returned by the function passed is used for initializing state.That is referred to as lazy state initialization. Lazy state initialization is necessary if you are performing a computationally expensive process for initializing state. Consider the example below:

import React from "react";

function initializer() {
  return Math.random();
}

function App() {
  const [state, setState] = React.useState(initializer());
  const clickHandler = React.useCallback(() => {
    setState(prev => prev + 1);
  }, []);
  return (
    <div className="App">
      <h1> {state} </h1>
      <h2>
        <button onClick={clickHandler}> Click </button>
      </h2>
    </div>
  );
}

In the example above, initializer is defined outside the component. It returns a random number which is used for initializing state. The initial state is ignored in subsequent renders but the function initializer which is used for initializing it is invoked in every re-render. This might not be a big problem if you are simply returning a random number like in the above example however it causes performance problems if initializer performs a computationally expensive process.

How do we get over this problem?

To solve the problem described above, you can pass a function which calls initializer as an argument, like:

 const [state, setState] = React.useState(() => initializer());

or else pass initializer to useState without invoking it like:

 const [state, setState] = React.useState(initializer);

The above two approaches ensure initializer is invoked on first render but ignored in subsequent re-renders.

Thanks for reading this article to the end. If you found it informative, consider sharing it on twitter or any other social media platform. Others might find it useful too.

References

Posted on by:

nibble0101 profile

Joseph Mawa

@nibble0101

Programming noob. Learning MERN stack.

Discussion

markdown guide