How to use Array.map to render a list of items in React
Tags: webdev, javascript, beginners, react
Published: 2022-12-17 16:12:22

One of the most common tasks for React developers is to render a list of data (e.g. users) onto a web page. And thanks to the the `Array.map` method this can be done in a simple and efficient way. In this article, you'll learn how JSX helps to make components in React as close to HTML as possible while still allowing you to write some JavaScript.

Let's start by looking at how to use JSX to render dynamic data to the page using React. If you want to insert a dynamic value into the HTML you can place an expression inside curly braces like so:

```
<h1>Hello {name}!</h1>
```

This is all fairly straightforward, but eventually you'll run into a situation where you want to insert a list of data into a component. Lists of data are fairly common in websites and apps, for example:

-   lists of tweets on Twitter
-   playlists of videos on YouTube
-   lists of photos on Instagram for example

And when you need to display insert a list of values in React, the `Array.map` function will become your new best friend!

Why not use for loops instead of map? 🤔
----------------------------------------

The reason for this is that you can't use `for` loops in JSX. This is because anything inside the curly braces in a component has to be an expression: which means you can't use imperative statements like `for` or `if`. But don't worry, JavaScript arrays have some powerful methods that will help you transform the data into a value that can be inserted directly into components.

How does map work?
------------------

`Array.map` works in a similar way as a mathematical function.

Take a look at the diagram below (from [Maths Is Fun](https://www.mathsisfun.com/sets/function.html)). It's a mathematical function mapping one set of numbers on the left, to another set of numbers on the right. The mapping is applying a rule to each number. Can you figure out what this rule is?

![https://www.mathsisfun.com/sets/images/function-sets-x2.svg](https://scrimba.com/articles/content/images/2022/11/Array-Mapping---how-it-works.png)

Hopefully you figured out that the rule is to square the number on the left (i.e. multiply it by itself) to get the number on the right. In mathematical notation, this would be written as:

n → n² 

(note how similar this looks to an arrow function in JavaScript by the way).

An array of values in JavaScript can be thought of as the sets of numbers used in the example above. The `Array.map` function allows us to apply the same function to everyvalue in an array and produce a new array containing the results. Each value in the original array maps to a corresponding value in the new array.

For example, consider the following array of purple shapes. If we apply the mapping function 'make green' to it then every shape in the original array gets mapped to a green-colored shape in the new array.

![](https://scrimba.com/articles/content/images/2022/11/Array-Mapping.png)

In a similar way, applying the 'make love' function to the following array of shapes will return an array where every element in the original array has been mapped to a love heart of the same color:

![](https://scrimba.com/articles/content/images/2022/11/Array-Mapping-1.png)

The `Array.map` method works in the same way as a mathematical function. It iterates over the array that calls the method and returns a new array, with each value from the calling array mapped to a corresponding new value, based on a mapping function.

For example, the following mapping function would double every number:

```
const double = n => 2 * n
```

The mapping function is provided as an argument to the `Array.map`method. Functions that are provided as an argument are often referred to as callbacks. The fact that `Array.map` accepts a function as an argument means that it is a higher order function, which is any function that accepts another function as an argument or returns a function.

Another important point is that the `Array.map` method doesn't mutate the original array that calls it. It returns a completely new array of new values and leaves the original array unchanged.

This ability to map each item in an array to a new value without changing the underlying structure of the array means that JavaScript arrays are examples of a [functor](https://en.wikipedia.org/wiki/Functor).

Array.map examples
------------------

Let's take a look at some examples of using the `Array.map` method in JavaScript.

### **Mapping numbers**

First of all, let's create an array of numbers that we can apply these mapping functions to:

```
const numbers = [1, 2, 3, 4, 5]
```

Now let's define some mapping functions that can be used to map one value to another:

```
const increment = n => n + 1
const double = n => 2 * n
const square = n => n * n
```

Here we have three mapping functions:

-   `increment` returns the next number after the argument
-   `double` returns the argument multiplied by 2
-   `square` returns the argument multiplied by itself

Let's have a go at using them:

```
numbers.map(increment)

// result [2,3,4,5,6]
```

As you can see, when the `increment` mapping function is provided as an argument, the array that is returned has the same number of elements as the `numbers` array, but each corresponding value has been incremented by one.

We can also confirm that the `numbers` array hasn't been changed by the operation:

```
numbers

// result [1, 2, 3, 4, 5]
```

If we provide the `double` mapping function as an argument, it will return an array where each value is twice as big as the corresponding value in the `numbers` array:

```
numbers.map(double)

// result [2, 4, 6, 8, 10]
```

Since the `Array.map` method returns a new array, it's often helpful to assign the returned value to a variable. For example, we can provide the `square` mapping function as an argument to the `numbers`array, which will return a new array that correspond to the [square numbers](https://en.wikipedia.org/wiki/Square_number), so it makes sense to assign the return value to the variable `squareNumbers`:

```
const squareNumbers = numbers.map(square)

// result [1, 4, 9, 16, 25]
```

If we don't have a named mapping function that performs the operation we need, we can provide an anonymous function as an argument. The following example will subtract each value in the `numbers` array from 10:

```
numbers.map(n => 10 - n)

// result [9, 8, 7, 6, 5]
```

We can also chain mappings together and apply two functions to each value in the `numbers` array:

```
numbers.map(double).map(increment)

// result [3, 5, 7, 9, 11]
```

This will double all the numbers and add one to them all. However, this is an example of just because you can do something, doesn't mean you should. If you want to double the numbers then add one, it would be much more efficient to write a new mapping function that does this instead of applying the [`Array.map`](http://array.map/) method twice. This is because every time you use the `Array.map` method, you loop over the array, so applying it twice will result in two passes of the array. This isn't much of a problem when the array isn't very long, but in reality you may be dealing with huge sets of data and should try and limit the number of times you loop over the array.

### **Mapping strings**

We can also use the `Array.map` method to transform an array of strings. To demonstrate this, let's create an array called `words`:

```
const words = ["hello","world"]
```

And let's create a mapping function that accepts a string as an argument and returns that string written in reverse:

```
 const reverse = string => [...string].reverse().join()
```

Providing the `reverse` mapping function as an argument to `words.map` will return a new array with each word written backwards:

```
words.map(reverse)

// result ["olleH", "dlroW"]
```

We can also use built-in string methods by providing an anonymous function as a callback that calls the method we want on each string in the array. In the following example, we call the `toUpperCase` string method on each word in the array:

```
words.map(word => word.toUpperCase())

// result ["HELLO", "WORLD"]
```

This returns a new array with each word written in capital letters.

A common pattern when mapping over strings is to insert them into HTML tags. For example, we could wrap heading tags around the words using the following mapping function:

```
const makeHeading = text => <h1>${text}</h1>
```

If we provide the `makeHeading` function as an argument to the mapping over the `words` array, it will return an array of HTML:

This HTML can then be inserted into a web page.

### **Mapping objects**

We can also use `Array.map` to extract information from a list of objects. For example, we could have a list of objects that describe different types of fruit, something like this:

```
const fruits = [
    { name: "Apple"
      price: 25
      emoji: "🍏"
    },
    { name: "Banana"
      price: 40
      emoji: "🍌"
    },
    { name: "Melon"
      price: 75
      emoji: "🍉"
    },
]
```

The first thing we can do is extract all the values of a specific property from each object. For example, if we only wanted to see the `emoji`property, we could use the following code:

```
fruits.map(fruit => fruit.emoji)

// result  ["🍏","🍌","🍉"]
```

This maps each object to a single value that corresponds to the `emoji` property of each object.

We can also map over an array of objects to create a string of HTML based on the object's values. The following code will create a list item based on each object in the `fruits` array:

```
const fruitList = fruit.map(
	fruit => `<li>${fruit.emoji} ${fruit.name}, ${fruit.price}c each</li>`)
```

This will return the following array of HTML:

```
["<li>🍏 Apple, 25c each</li>","<li>🍌 Banana, 40 each</li>","<li>🍉 Melon, 75c each</li>"]
```

This example shows how you can take a load of data stored in an array of objects and use map to create an array of HTML. This is the foundation of using `Array.map` to create JSX code that can be used in React components.

Using map in React
------------------

The `Array.map` function comes into its own when we need to insert a list of data from an array into a JSX component. Let's take a look at a simple example using this array of super heroes:

```
const heroes = ["Superman", "Batman", "Wonder Woman"]
```

We can create a component that uses `Array.map` to iterate over each super hero in the `heroes` array and create a level-1 heading containing the name of each super hero:

```
const Headings = () => {
  const headings = heroes.map((hero, index)=>
    <h1 key={index}>{hero}</h1>)
  return <header>{headings}</header>
}
```

The return value of `Array.map` is stored in the variable `headings`. This can now be inserted as an expression into the return value of the the `Headings` component. Each element in the `heroes` array will then be rendered as a heading.

You can see [this example on CodePen](https://codepen.io/daz4126/pen/xxzxRxG).

This example shows how easy it is to use `Array.map` to display a list of data using a single line of code.

### **Using keys**

An important point to remember when using `Array.map` to create a list of items in React is that you must provide a `key` prop. This is used by React in the background to keep track of the order of the items in the list. It becomes particularly important if the items in the list are likely to change order or if items are added or removed from the list.

React uses a [virtual DOM](https://reactjs.org/docs/faq-internals.html) to keep track of any changes that are made and keys are important in making sure that these changes are as rendered in the most efficient way possible.

An easy way to create a `key` prop is to use the index of the array:

```
const Headings = () => {
	const headings = heroes.map((hero,index) => <h1 key={index}>{hero}</h1>)
	return <header>{headings}</header>
}
```

This is not best practice however, as the index of each element will change if the underlying data changes and won't help the virtual DOM keep track of any changes.

Ideally each element needs to use a unique value as its `key` prop. Thankfully most data provided by a database or API usually comes with unique IDs that we can use as the `key` prop.

### **Lists of objects**

Let's finish off by looking at a more realistic example where you have an array of objects that have been pulled from a database or external API. For example, the following list of coding books:

```
const books = [
  { id: "B09123N2QN",
   title: "Learn To Code With JavaScript",
   author: "Darren Jones",
   price: 2260,
   pages: 425,
   cover: "https://m.media-amazon.com/images/I/412KSS+3fjL._SX260_.jpg",
   keywords: ["coding", "javascript", "beginner"]
 },
  { id: "B088P9Q6BB",
   title: "JavaScript: The Definitive Guide",
   author: "David Flanagan",
   price: 2399,
   pages: 708,
   cover: "https://m.media-amazon.com/images/I/51wijnc-Y8L._SX260_.jpg",
   keywords: ["rhino", "javascript", "mastery"]
 },
  { id: "B07C96Q217",
   title: "Eloquent JavaScript",
   author: "Marijn Haverbeke",
   price: 1994,
   pages: 474,
   cover: "https://m.media-amazon.com/images/I/51-5ZXYtcML.jpg",
   keywords: ["eloquent", "javascript", "modern"]
 },
]
```

If we wanted to display a list of books, showing the title and cover, we could create a Book component that returned the JSX we required:

```
const Book = ({id,title,cover}) =>
  <li key={id}>
    <h2>{title}</h2>
    <img alt={`cover of ${title}`} src={cover} />
  </li>
```

This takes the book object and uses destructuring in the parameter list to extract the `id`, `title` and `cover` properties. These are then used to return a list item that displays the title as a level-1 heading and the cover of the book as an image.

Now we can create a `BookList` component that uses `Array.map` to create a list of books by using the `Book` function as the mapping function that is provided as an argument:

```
const BookList = () =>
    <div>
      <h1>Books</h1>
      <ul>
        {books.map(Book)}
      </ul>
    </div>
```

The `BookList` component creates a container `<div>` and heading and then provides the `<ul>` elements to contain the list of books. We then use `Array.map` to loop over the list of books and insert a `Book` component in place of each value in the `books`array.

You can see [this example on CodePen](https://codepen.io/daz4126/pen/QWxLYBX).

### **Limiting the list**

This is fine in this case as the `books` array only contains 3 books, but in reality an API might return hundreds of book objects, so how can you limit the number of books that are displayed using the `map`method? It's actually quite straightforward, you can just use the `slice` method to cut the array down to size, for example, if you only want to display the first 2 books, you can update the `BookList`component to the following:

```
const BookList = ({n}) =>
    <div>
      <h1>Books</h1>
      <ul>
        {books.slice(0,n).map(Book)}
      </ul>
    </div>
```

It's much better to slice the array before applying the map function as avoids the whole of the `books` array being iterated over.

We can make the `BookList` component a bit more general by providing the number of books to display in the list as a prop, to the component:

```
const BookList = ({n}) =>
    <div>
      <h1>Books</h1>
      <ul>
        {books.slice(0,n).map(Book)}
      </ul>
    </div>
```

Now we can choose the value of `n` that will determine the number of books displayed in the list. This is called when we render the `BookList` component, like so:

```
ReactDOM.render(<BookList n={2} />, document.getElementById("root"))
```

### **Displaying data in a table**

The last example used `map` to create an unordered list of items, which is an obvious way to present data from an array, but we can also use it to iterate over data and present it in other ways as well, for example we could create a table to display all the information about our `books` array:

```
const BookRow = ({id,title,author,price,pages}) =>
  <tr key={id}>
    <td>{title}</td>
    <td>{author}</td>
    <td>{pages}</td>
    <td>£{price/100}</td>
  </tr>
```

Then we can create the actual table to hold all these rows:

```
const BookTable = () =>
    <div>
      <h1>Books</h1>
      <table>
        <thead>
          <th>Title</th>
          <th>Author</th>
          <th>Number of Pages</th>
          <th>Price</th>
        </thead>
        <tbody>
        {books.map(BookRow)}
        </tbody>
      </table>
    </div>
```

This sets up the table and table headings and then after the heading row, we use `Array.map` to map over each book in the `books`array and pass it to the `BookRow`component. This has the effect of creating a new row for every element in the `books`array.

You can see [this example on CodePen](https://codepen.io/daz4126/pen/BaVBbXz).

### **Creating a nested list**

Sometimes an array will contain objects that also contain arrays as properties. These might need to be mapped over as well in order to display them using JSX. In this case we can create a nested map statement.

For example, our `books` array contains a property called `keywords` which is an array of key words about each book. What if we wanted to display the title of each book with its keywords listed underneath like tags?

First of all we could create `Tag` component:

```
const Tag = word =>
  <div className="tag">{word}</div>
```

Then we create a `Book` component, similar to the one we used earlier:

```
const Book = ({id,title,keywords}) =>
  <li key={id}>
    <h2>{title}</h2>
  <div>{keywords.map(Tag)}</div>
  </li>
```

This time we use `Array.map` again map over the keywords array, which will insert a new `Tag` component inside a `<div>` element for each keyword in the array.

Last of all we need a `BookList` component that will map over the `books` array and create a list of `Book` components (this component is exactly the same as the one we used earlier):

```
const BookList = ({n}) =>
    <div>
      <h1>Books</h1>
      <ul>
        {books.slice(0,n).map(Book)}
      </ul>
    </div>
```

You can see an [example on CodePen](https://codepen.io/daz4126/pen/jOKNRGz).

We can see here that the `Array.map` in the `BookList`component iterates over the `books` array and then the `Array.map` in the `Book` component iterates over every element in the keywords property of every element in the  `books` array.

The verdict
-----------

The [Array.map](http://array.map/) method is a powerful higher-order function that lets you transform all the values in an array using a mapping function. This is especially useful for inserting a list of data into a React app, since you can't use `for` loops. It lets you replace elements in an array with a component based on the data in the array. When dealing with data that will change, it is important that you provide a unique `key`prop for each component in the list. Once you've got the hang of using the Array.mapmethod to display lists of data into React, you'll wonder how you ever managed without it!