Understanding the React useState() Hook
Tags: react, programming, javascript, webdev
Published: 2021-04-17 07:22:43

## Introduction

[Hooks](https://reactjs.org/docs/hooks-intro.html) were introduced in React **v16.8.0**. Prior to that, if we had written a functional component and wanted to add `state` or make use of `lifecycle` methods to perform operations such as data fetching and manual DOM manipulation, the functional component had to be converted into class based component.

However, introduction of Hooks made adding state and performing those operations in functional component possible. It also helped in keeping the mutually related code together rather than splitting the code based on lifecycle methods. Hooks don't work inside classes rather they let us work with React without the need for class.

In this post, we will learn about the built-in **useState()** Hook and how to use it in a functional component. We will also understand the difference in initializing, updating and accessing the state in class component as compared to functional component.

## Rules of Hooks

Following are the two rules of Hooks that needs to be followed:

- Hooks should always be called at the top level of the React function which means it shouldn't be called inside loops, conditionals or nested functions. This is done to ensure that Hooks are called in the same order each time a component renders.

- Never call Hooks from regular JavaScript functions. Instead, call it from React function components or [custom Hooks](https://reactjs.org/docs/hooks-custom.html).

## useState() Hook

As the name suggests, `useState` Hook is used to add state to function components.

The syntax for useState is as below:
```javascript
const [state, setState] = useState(initialState);

// assigns initialState to state
// setState function is used to update the state
```

useState() returns an `array` with exact two values. Array destructuring can be used to store these values in different variables.

The first value returned represents the state and the second value returned is a function that can be used to update the state. You can give any name to these two variables. For our understanding, we'll name the state variable as `state` and the function that updates it as `setState`. You can follow this convention of assigning any name to state variable and then prefixing it with 'set' to form the function name.

The 'initialState' argument passed to useState sets the initial state. On subsequent re-renders, state is updated through the `setState` function returned from the `useState` Hook.

Now, let's take a look at the following code block which represents a **class component** with state

```javascript
import React, { Component } from "react";

export default class App extends Component {

  constructor(props) {
    super(props);
    this.state = {
      weather: 'hot',
      disabled: false
    }
  }

  render() {
    return (
      <div>
        <p>The weather is {this.state.weather}</p>
        <button 
            onClick={() => this.setState({weather: 'cloudy', disabled: !this.state.disabled})} 
            disabled={this.state.disabled}>
            Change weather
        </button>
      </div>
    );
  }
}
```

When the above class component gets rendered to the screen, you get a paragraph `The weather is hot` with a 'Change weather' button below it.

On clicking the button, the component re-renders and output changes to `The weather is cloudy` with the button getting disabled.

In a class component, you can initialize state in the constructor by using `this.state`. In the above example, it is initialized to `{weather: 'hot', disabled: false}`. Any update to state is done through `this.setState` and respective values can be accessed using `this.state.weather` and `this.state.disabled`.

The state is defined as an object and all the state updates done through `this.setState` is merged into that object as class component can have a single state object only. Therefore, `{weather: 'cloudy', disabled: !this.state.disabled}` gets merged with the previous value and state is updated. 

*In order to initialize, update or access any value from state in a class component, you always need to use `this` keyword.*

Now, let's take a look at the following **functional component** using the **State Hook** that works the same way as the earlier class component

```javascript
// import useState Hook from "react" package
import React, { useState } from "react";

export default function App() {

  const [weather, setWeather] = useState('hot');    // "weather" value initialized to "hot"
  const [disabled, setDisabled] = useState(false);  // "disabled" value initialized to "false" 
  return (
    <div>
      <p>The weather is {weather}</p>
      <button onClick={() => {
        setWeather('cloudy');     // setWeather('cloudy') updates the "weather" to "cloudy"
        setDisabled(!disabled);   // setDisabled(!disabled) updates the "disabled" to "true"
      }} disabled={disabled}>Change weather</button>
    </div>
  );
}
```

- In order to use state in functional component, you first need to import `useState` Hook from React.

- Unlike class component where you can have a single state object only, functional component allows you to have multiple state variables. Here, `weather` and `disabled` state variables are initialized to the argument passed to `useState` Hook.

- This argument can be of any type such as number, string, array or object unlike class component where state is initialized to object only.

- On clicking the button, `setWeather` and `setDisabled` functions are called with new state values passed to it. React will then re-render the component by passing the new `weather` and `disabled` values to it.

- In a functional component, updating a state value always replaces the previous value unlike class component where state updates are merged.

In the above example, new state values are not dependent on previous state values. Therefore, we directly pass new value to state update function. In scenarios where new state value depends on previous state value, you can use the following functional update format to update the state.

```javascript
setState(previousStateValue => {
    // newStateValue determined using previousStateValue
    return newStateValue;
})
```

This functional update format is used to update the state depending on the previous state value.

## Conclusion

In this post, you learnt about the **useState()** Hook that makes it possible to use state in a functional component without transforming it into a class component. You learnt how to initialize, update and access the state variables in a functional component using Hooks.
___

Thank you for taking the time to read this post 😊
Hope this post helped you!! **Please share** if you liked it.

I would love to connect with you on [Twitter](https://twitter.com/_raunaq_).
Do share your valuable feedback and suggestions you have for me 👋