In this article, we are going to take a look at a simple example to understand how to use the state hook when the state variable is an array?

Let me create a new file called HookCounterFour.js and within the file I am going to create a functional component.

Functional Component

import React from 'react'

function HookCounterFour() {
return (
<div>
</div>
)
}

export default HookCounterFour

Declare a state variable using the useState hook

import useState and then de-structure items and setItems from useState and since we are working with arrays, for this example, the default value is an empty array.

import React, { useState } from 'react'

function HookCounterFour() {
const [items, setItems] = useState([])

return (
<div>
</div>
)
}

export default HookCounterFour

Render the items in the JSX

We are using map function to get each item and then render a list item.

The key is going to be item.id and the value is item.value

import React, { useState } from 'react'

function HookCounterFour() {
const [items, setItems] = useState([])

return (
<div>
<ul>
{items.map(item => (
<li key={item.id}>{item.value}</li>
))}
</ul>
</div>
)
}

export default HookCounterFour

Add items to Array

We are dealing with an array of objects and we don't really have any items to begin with.

So let's add a button at the top which pushes new items into the array.

Button the text is add a member and onClick we are going to call a function addItem().

Now let's define the addItem function 

import React, { useState } from 'react'

function HookCounterFour() {
const [items, setItems] = useState([])

const addItem = () => {
setItems([
...items,
{
id: items.length,
value: Math.floor(Math.random() * 10) + 1
}
])
}

return (
<div>
<button onClick={addItem}>Add a number</button>
<ul>
{items.map(item => (
<li key={item.id}>{item.value}</li>
))}
</ul>
</div>
)
}

export default HookCounterFour

Const add item is equal to an arrow function and within the function we call the setItems setter function, now we need to pass in the value to set for the items array and we learned in the last article that the setter function doesn't merge and update. In the case of an array the setter function doesn't automatically append the item to the end of the list.  We need to handle that manually using the spread operator, which is pretty simple as we saw in the last article.

So the argument to setItems will be an array and first we spread the items array and then we push a new object.

For the new object,  the ID is going to be items.length and the value is going to be a random number between 1 and 10. So value Math.floor(Math.random() * 10) + 1, so basically a random number between 1 and 10. 


Now let me explain what is happening here whenever addItem is called we make a copy of all the items in the array using the spread operator, to that list of copied items we simply append another object, that way we are not overwriting the original array.

On first iteration items is an empty array, so ID will be 0 which is items dot length, the value will be a random number between 1 and 10, on the next iteration we would have one item in the items array so we make a copy of that and to that we append a new object, the ID this time will be items dot length which is equal to 1 and the value of course will be a random number and the same logic continues for subsequent button clicks.


Lets include HookCounterFour in App,js

import React, { Component } from 'react'
import './App.css'
import HookCounterFour from './components/HookCounterFour'

class App extends Component {
render() {
return (
<div className="App">
<HookCounterFour />
</div>
)
}
}

export default App

If we now go back to the browser and click on the button you can see that new items are added to the state variable, so a pretty simple example but what I wanted to show is how you work with you state and arrays.

Make a copy using the spread operator append the new item and pass it as argument to the setter function.

Alright with that we come to the end of the different details we had to learn about the useState hook

Summary - useState

The useState hook lets you add state to functional components( by calling you state inside a functional component you are creating a single piece of state)

In classes the state is always an object you can store properties on that object 

With the useState hook the state doesn't have to be an object, it can be an array, a number, a boolean, a string etc 

The useState hook returns an array with two elements, the first element is the current value of the state and the second element is a state setter function.

You call the set of function with a new value to set the state which will in turn cause the component to re-render 

In case your new state value depends on the previous state value you can pass a function to the setter function, the setter function will receive the previous state as its argument.

Finally, when dealing with objects or arrays always make sure to spread your state variable and then call the setter function to get the expected behaviour.

To learn more about UseState hook, please go through below links

React hooks introduction

React useState hook

How to set state based on the previous state value?

How to use an object as a state variable with the useState hook