The State Hook
Arrays in State

Think about the last time that you ordered a pizza online. Mmmmm…

Part of the magical website that brought you tasty food was built with code like this:

import React, { useState } from "react"; const options = ["Bell Pepper", "Sausage", "Pepperoni", "Pineapple"]; export default function PersonalPizza() { const [selected, setSelected] = useState([]); const toggleTopping = ({target}) => { const clickedTopping = target.value; setSelected((prev) => { // check if clicked topping is already selected if (prev.includes(clickedTopping)) { // filter the clicked topping out of state return prev.filter(t => t !== clickedTopping); } else { // add the clicked topping to our state return [clickedTopping, ...prev]; } }); }; return ( <div> {options.map(option => ( <button value={option} onClick={toggleTopping} key={option}> {selected.includes(option) ? "Remove " : "Add "} {option} </button> ))} <p>Order a {selected.join(", ")} pizza</p> </div> ); }

JavaScript arrays are the best data model for managing and rendering JSX lists. In this example, we are using two arrays:

  • options is an array that contains the names of all of the pizza toppings available
  • selected is an array representing the selected toppings for our personal pizza

The options array contains static data, meaning that it does not change. We like to define static data models outside of our function components since they don’t need to be recreated each time our component re-renders. In our JSX, we use the map method to render a button for each of the toppings in our options array.

The selected array contains dynamic data, meaning that it changes, usually based on a user’s actions. We initialize selected as an empty array. When a button is clicked, the toggleTopping event handler is called. Notice how this event handler uses information from the event object to determine which topping was clicked.

When updating an array in state, we do not just add new data to the previous array. We replace the previous array with a brand new array. This means that any information that we want to save from the previous array needs to be explicitly copied over to our new array. That’s what this spread syntax does for us: ...prev.

Notice how we use the includes(), filter(), and map() methods of our arrays. If these are new to you, or you just want a refresher, take a minute to review these array methods. We don’t need to be full-fledged JavaScript gurus to build React UIs, but know that investing time to strengthen our JavaScript skills, will always help us do more faster (and have a lot more fun doing it) as React developers.



Declare and initialize a state variable called cart that will keep track of a list of string values. Each of these string values represents a grocery item that we’ve added to our shopping cart. We’ll add event listeners and event handlers to add and remove items to our cart in the coming steps. For now, let’s get started by initializing our cart with the value of an empty array for the first render.


Add parameters to our two event handlers. addItem() should accept an argument called item and removeItem() should accept an item called targetIndex. Don’t worry about writing the function body for these event handlers just yet, we’ll do that in the next few steps!


Use array spread syntax to add a new item to our cart state when the addItem() function is called.


When the removeItem() function is called, use the array filter() method to remove the item from our state that’s located at the index of the item that was clicked in our list.

Why would we want to use the index of the clicked item instead of the item itself when determining what to remove from our data model? Say that we have two of the same item in an array. Using the value to remove the item would remove all items with that value, so we use the index as a unique identifier.

Folder Icon

Take this course for free

Already have an account?