When building any type of web application, it's very common that you will need to handle an array of data. In this article, let me show you how to loop through an array of data using React best practices, using real-world examples that you can take away and use in your own web applications.
Have you used the map function before?
The map()
method creates a new array with the results of calling a provided function on every element in the calling array.
So the map function was introduced to JavaScript in ES2015. It greatly simplifies the looping process and cuts out the need to use a simply for loop or a forEach function. Now there are some differences between for loop, forEach and map, but we won't go into them here. The React docs strongly encourage the use of the map function, not just for its simplicity, but because it creates a new array from the data, rather than trying to mutate/overwrite existing data.
This second point is vital. If you are unsure about how to use map functions, I recommend that you take a moment to read this article about using map, filter and reduce.
Looping through an array of items in a shopping cart
Let us imagine that we are building an eCommerce website where we sell clothes. Our application will likely have a shopping cart that items get added to. So to begin with, our shopping cart will look something like this.
let shoppingCart = [];
But after a few items have been added, it may look something like this:
let shoppingCart = [
{ id: 35, item: "jumper", color: "red", size: "medium", price: 20 },
{ id: 42, item: "shirt", color: "blue", size: "medium", price: 15 },
{ id: 71, item: "socks", color: "black", size: "all", price: 5 },
];
Now on our shopping cart page, we will want to output these items so that the user can see what they have ordered. Let's see two very similar ways that we can handle this.
Inside of our App class constructor, we will create this.items and assign it to this.state.cart (remember, this is where we store items that get added to the cart). We then use the ES2015 map function to loop through each item in this.state.cart.
We pass our map function two parameters. The first is item which simply corresponds to a single item inside of our this.state.cart array. The second is a key, which React uses to help its renderer keep a track of each individual item. As you may have noticed, we didn't set a key inside of our this.state.cart
, we simply pass the item's id as the key, by referencing item.id inside of our map function. Anyway, we then output an tag with {item.name} inside of it.
Let's just take a quick look at how this chunk of code in full:
this.items = this.state.cart.map((item) => <li key={item.id}>{item.name}</li>);
Then later on in our code, when we want to use it, we simply create an outer tag, and put this.items
inside of it, like so:
<ul>{this.items}</ul>
And just like that, our page will render each item in our shopping cart as a unique <li>
item.
The second way that we could have handled this is very similar, and may feel a little more familiar.
Instead of putting our this.item block of code inside of the class constructor, we could have simply put it at the top of our render()
function, like so:
render() {
const items = this.state.cart.map((item) =>
<li key={item.id}>{item.name}</li>
);
This allows us to use the more traditional const syntax (or var or let if you prefer).
If we do this, it also means that we can write this instead:
<ul>{items}</ul>
Now some people will argue that you shouldn't pollute the render()
function, but when writing something fairly simple and not incredibly complex (I'm talking about thousands and thousands of lines of code here), it really doesn't matter. So I would recommend that you go with whichever way feels more comfortable to you. As you progress with React, you will come to find a style that suits your project best.
Okay, so we know how to render lists using loops. But what if we want to loop through data to output lots of child components? How can we do this?
Well, it's actually quite simple and very similar to what we have already been doing.
So let us just imagine that our shop has the following items:
shop: [
{ id: 35, name: "jumper", color: "red", price: 20 },
{ id: 42, name: "shirt", color: "blue", price: 15 },
{ id: 56, name: "pants", color: "green", price: 25 },
{ id: 71, name: "socks", color: "black", price: 5 },
{ id: 72, name: "socks", color: "white", price: 5 },
];
And just to give you a clearer picture, this shop exists inside of this.state
, inside of a constructor. It all looks like this:
class App extends Component {
constructor(props) {
super(props);
this.state = {
cart: [],
shop: [
{id: 35, name: 'jumper', color: 'red', price: 20},
{id: 42, name: 'shirt', color: 'blue', price: 15},
{id: 56, name: 'pants', color: 'green', price: 25},
{id: 71, name: 'socks', color: 'black', price: 5},
{id: 72, name: 'socks', color: 'white', price: 5},
]
}
}
Note: This post was written before the creation of React Hooks. Therefore, class components were used instead of functional components. However, the principles still remain with regard to looping through React components.
So we have our shop items and now we want to create a child component which we call Item.js. The entire component file looks like this:
import React, { Component } from "react";
class Item extends Component {
render() {
return (
<div>
<p>{this.props.item.name}</p>
<p>{this.props.item.color}</p>
<p>${this.props.item.price}</p>
</div>
);
}
}
export default Item;
If you are unsure, we call this.props.item because we pass this.state.item into the child component when we call for it inside of the parent component. This may sound a bit strange, but bear with us and it will all make sense in a moment!
So going back to looping, this is what we would write to loop through the items in our shop:
<h3>Items for sale</h3>;
{
this.state.shop.map((item) => <Item key={item.id} item={item} />);
}
As you can see, it's pretty much the same concept that we used earlier. The only difference here is that instead of outputting <li>
tags, we are now outputting <Item />
tags instead — which is the Item.js component we mentioned a moment ago! It's as simple as that!
So when we call this.props.item inside of the Item.js component, it is a reference to <Item key={item.id} item={item}/>
, more specifically, item={item}. So if we called this product={item}, we would, instead, refer to this.props.product. Make sense?
You may have noticed that we had to wrap the entire functionality inside of curly braces {}. This is required so that React is able to understand that you are trying to express a function and not just render out plain text.
Another thing to also note here is that the three different ways we have looped through data can all be interchanged. So if you wanted to loop through an array of child components, but preferred the first method we showed you, then you can! At the end of the day, it's all regular JavaScript!
So there you have it, we have shown you three powerful ways to loop through arrays using the latest JavaScript techniques in React. Now go use this newfound knowledge to make some amazing web applications!