ReactJS useState Hook - lazy initialization and previous state
Tags: react, javascript, beginners, codenewbie
Published: 2022-02-18 05:45:34

## The State of a Component

ReactJS is a component-based user interface library. Each of the components we create should have an individual responsibility. In the real world ReactJS application, components need to interact by exchanging information or data. There are several ways components can talk to each other, like passing `props`, creating a single source `data context`, or a `store` to read and write data.

While this interaction makes the app dynamic, components also need to handle private information. Every component needs to track this information change to drive an outcome. The component's private information(or data) is called `state`.

![component-composition.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1645092740548/8HFypLJb_.png)

The image above shows the representation of the component's state and the props it passes across.

## The `useState` Hook

With the invent of the functional components in ReactJS, we can perform state management using a famous hook called `useState`. We declare and track the component's state using this hook. It takes an optional argument as the initial state value and returns the current state and a function to update it.

```js
const [counter, setCounter] = useState(1);
```
In the above code snippet, we initialize the `counter` state with the value of `1`, and the variable `counter` will always give us the current state value. If we want to update the state, we do not directly update the `counter` variable. Instead, we will explicitly call the `setCounter()` method and update the state value.

```js
const incrBy3() => {
   setCounter(counter + 3);
}
```
The method `incrBy3()` update the current state by incrementing the counter value by `3`. The update of a state triggers the re-rendering of your component. It means the `useState` hook gets called internally to provide you with the updated `counter` value that you may use in your JSX.

```html
<div className="counter-box">
    <span>{ counter }</span>
    <button onClick={incrBy3}>+ 3</button>
</div>
```
The above snippet shows the JSX code that renders the current state value(`counter`) and a button click-event that uses the updater function(`setCounter()`) to change the state. 

If we put everything together in a ReactJS component, it will look like this,

```js
import React, { useState } from 'react';

export default function App() {
  const [counter, setCounter] = useState(1);

  const incrBy3 = () => {
    setCounter(counter + 3);
  };

  return (
    <div className="container">
      <h1>Increment By 3</h1>
      <div className="counter-box">
        <span>{ counter }</span>
        <button onClick={incrBy3}>+ 3</button>
      </div>
    </div>
  );
}
```
The output,

![output-1.gif](https://cdn.hashnode.com/res/hashnode/image/upload/v1645083991371/Sa9Zn0bNu.gif)

That's great!!! But, what about the `Lazy Initialization` and `Previous State` 😲? Oh yes, let's get to that.

## Interesting Facts of `useState` Hook
A few points to emphasize here that we often ignore.

- With the `useState` hook, the state gets created only at the first render using the initial value we pass as an argument to it.
- For every re-render (subsequent renders after the initial render), ReactJS ignores the initial value we pass as the argument. In this case, it returns the current value of the state.
- ReactJS provides us with a mechanism to get the previous state value when dealing with the current state value.

That's all about the interesting facts, but they may not make much sense without understanding their advantages. So, there are two primary advantages,

- We can perform a lazy initialization of the state.
- We can use the previous state value alongside the current one to solve a use case. 

Let's learn them with examples below.

### How to perform Lazy Initialization of the State?

If the initial state value is simple data like a number, string, etc., we are good with how we have created and initialized the state in the above example. At times, you may want to initialize the state with a computed value. The computation can be an intense and time-taking activity.

With the `useState` hook, you can pass a function as an argument to initialize the state lazily. As discussed, the initial value is needed only once at the first render. There is no point in performing this heavy computation on the subsequent renders.
 
```js
const [counter, setCounter] = useState(() => Math.floor(Math.random() * 16));
```
The code snippet above lazily initializes the `counter` state with a random number. Please note, you don't have to do this always, but the knowledge is worthy. Now you know you have a way to perform lazy state initialization.

### How to Get the Previous State Data and Use it?
The `useState` hook returns a function to update the state. In our example, we know it as the `setCounter(value)` method. A specialty of this method is, you can get the previous(or old) state value to update the state. Please take a look into the code snippet below,

```js
const incrBy3 = () => {
    setCounter((prev) => prev + 3);
};
```
Here we pass a callback function to the `setCounter()` method gives us the previous value to use. Isn't that amazing?

Please find the updated source code with lazy initialization and previous state value usages from here: [The Source Code on Stackblitz](https://stackblitz.com/edit/usestate-lazy-load-prev-state?embed=1&file=src/App.js)

## Conclusion
To conclude, ReactJS's standard hooks got lots to offer when you use functional components. The `useState` hook helps us create and track the state changes. Knowing the extra bit of information about the `lazy initialization` and `previous state` value may help us deal with situations.

Are you new to RaectJS and the ecosystem around it or want to understand the fundamentals? I have started a series of videos to help you understand `ReactJS` practically and fundamentally. Here is a video from the series you may find helpful.

{% youtube N_Lfqk6oQ7o %}

<hr />
That's all for now. I hope you found this article insightful. 

I share my knowledge on,

- 🌐 Web Development(JavaScript, ReactJS, Next.js, Node.js, so on...)
- 🛡️  Web Security
- 💼 Career Development
- 🌱 Opensource
- ✍️ Content Creation 

Let's connect,

- [Give a Follow on Twitter](https://twitter.com/tapasadhikary)
- [Subscribe to my YouTube Channel](https://www.youtube.com/tapasadhikary?sub_confirmation=1)
- [Side projects on GitHub](https://github.com/atapas)
- [Showwcase React Community](https://www.showwcase.com/community/react.js)