A ReactJS Hook : useState()
Tags: javascript, webdev, beginners, react
Published: 2022-05-19 08:12:02

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uhettzsp2zvfxwch558a.png)
 **useState** is a Hook that enables state variables to be used in functional components. This function takes the initial state and returns a variable with the current state value and another function to update it.

In React, there are two type of components class based and functional based. Functional components are simple functions that accept parameters as component properties and return valid JSX:

```
function React(props) {
  return <div>{props.useState}</div>
}
// Or as an arrow function
const React = (props) =>  <div>{props.useState}</div>

```
There are no state or lifecycle methods, as you can see. 

React Hooks are the functions that add state variables to functional components. They usually begin with the keyword **_use_**.

## How to use `useState` Hook in ReactJS? What does it do?

useState allows you to add state to function components, as previously indicated. When you use useState inside a function component, it creates a single piece of state for that component.

Whereas in a class, the state is always an object, Hooks' state can be any type. Each state item contains a single value, which can be an object, an array, a boolean, or any other kind you can think of.

So, when is it appropriate to utilize the useState Hook? It's particularly effective for the local component state, but larger projects may require the usage of additional state management methods.

## Declaring` { useState } `in your React App.

To use the UseState hook in your App simply type the following code:

```
import React, { useState } from 'react';
```
The `useState` Hook allows you to declare only one state variable (of any type) at a time, like this:

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

const React= () => {
   const message = useState( '' );
   const listOfMessage = useState( [] );
}
```
`useState `takes the initial value of the state variable as an argument.


You can pass it directly, as shown in the previous example, or use a function to initialize the variable.

```
const Message= () => {
   const message = useState( () => helloWorld() );
}
```
The initial value will only be assigned on the first render and if it's a function, it will only be called on the first render.

The initial parameter of the useState Hook will be ignored in subsequent renders (due to a change of state in the component or a parent component) and the current value will be obtained.

Because its argument is only used for the first time — not every time the property changes — using useState alone won't work.

However, unlike the previous examples, useState does not just return a variable.

It returns an array with the state variable as the first element and a function to update the variable's value as the second element.

`Array destructuring `is commonly used to simplify the code.

```
const React= () => {
   const [message, setMessage]= useState( '' );
}
```
##Updating the `useState` in React Hooks

The second element returned by `useState` is a function that updates the state variable with a new value.

Here's an example of how to update the state variable.

```
const React = () => {
  const [message, setMessage] = useState( '' );

  return (
    <div>
      <input
         type="text"
         value={message}
         placeholder="Enter a text"
         onChange={e => setMessage(e.target.value)}
       /
  </div>
  );
};
```
This update function, on the other hand, does not immediately update the value.

  The `useState` parameter will be ignored after re-rendering the component, and this function will return the most recent value or the new state values.

##Using state varibales as an object: In `useState()` Hooks

If we add another property to the message object (id) like in the previous example:

```
const React = () => {
  const [messageObj, setMessage] = useState({ message: '', id: 1 });

  return (
    <div>
      <input
        type="text"
        value={messageObj.message}
        placeholder="Enter a message"
        onChange={e => {
          const newMessageObj = { message: e.target.value };
          setMessage(newMessageObj); 
        }}
      />
      <p>
        <strong>{messageObj.id} : {messageObj.message}</strong>
      </p>
  </div>
  );
};
```
And we only update the` message `property like in the above example, React will replace the original state object:

```
{ message: '', id: 1 }
```
With the object used in the `onChange` event, which only contains the message property:

```
{ message: 'message entered' } // id property is lost
```
You may replicate the behavior of setState() by passing the object to be replaced as a function argument and using the object `spread` syntax:

```
onChange={e => {
  const val = e.target.value;
  setMessage(prevState => {
    return { ...prevState, message: val }
  });
}}
```
The `...prevState` part will get all of the properties of the object and the `message: value` part will overwrite the `message `property.

You just have to be careful when applying the `spread `syntax to multidimensional arrays because it won’t work as you might expect.

This leads us to another thing to consider when working with objects as the state.

##Updating state in React hooks: For Nested objects

In JavaScript, multidimensional arrays are arrays within arrays:

```
[
  ['value1','value2'],
  ['value3','value4']
]
```
You could use them to centralize all of your state variables. However, it is preferable to use nested objects for this purpose:

```
{
  'row1' : {
    'key1' : 'value1',
    'key2' : 'value2'
  },
  'row2' : {
    'key3' : 'value3',
    'key4' : 'value4'
  }
}
```
However, when working with multidimensional arrays and nested objects, the `spread` syntax and `Object. assign` will create a shallow copy rather than a deep copy.

When copying an array, the `spread `syntax essentially goes one level deep. As a result, as the following example shows, it may not be suited for copying multidimensional arrays. (The same is true for `spread` syntax and `Object.assign()`.)

```
let a = [[1], [2], [3]];
let b = [...a];

b.shift().shift(); //  1
//  Array 'a' is affected as well: [[], [2], [3]]
```
but the important point is that when using nested objects, we can’t just use the spread syntax to update the state object.

For example, consider the following state object:

```
const [msgObj, setMsg] = useState({
  author: '',
  msg: {
    id: 1,
    text: ''
  }
});
```
The following code snippets show some incorrect ways to update the text field:

```
// Wrong
setMsg(prevState => ({
  ...prevState,
  text: 'My message'
}));

// Wrong
setMsg(prevState => ({
  ...prevState.msg,
  text: 'My message'
}));

// Wrong
setMsg(prevState => ({
  ...prevState,
  msg: {
    text: 'My message'
  }
}));
```
To properly update the text field, we have to copy to a new object the entire set of fields/nested objects of the original object

```
// Correct
setMsg(prevState => ({
  ...prevState,      
  msg: {             
    ...prevState.msg, 
    text: 'My message'    
  }
}));
```
In the same way, here’s how you’d update the author field of the state object:

```
// Correct
setMsg(prevState => ({
  author: 'Joe',      
  ...prevState.msg  
}));
```
Assuming the message object doesn’t change. If it does change, you’d have to update the object this way:

```
// Correct
setMsg(prevState => ({
  author: 'Joe',         
  msg: {              
    ...prevState.msg, 
    text: 'My message'    
  }
}));
```
##Conculsion

`useState` is a Hook (function) that enables state variables to be used in functional components. This function takes the initial state and returns a variable with the current state value (not necessarily the starting state) and another function to update it.