Course: Section

Get Started with Modern React: Step by Step

Episode: Title

S02・V14: Lists and Keys (Part 1)

Date Created: July 17th, 2019
Last Updated: 27 days ago

Objectives
  1. We will demonstrate how to map over an array of elements and render them.
  2. We will show that a key is necessary when rendering a list of elements.
  3. We will show that if a stable and unique I.D. is not available as a key, then we can use the array item index as a last resort.
Watch Video
Duration: 7m 22s

Mapping over an Array

In JavaScript, you can map over an array to return a new array with the result of each element transformed by a function.

Let’s start with an array of numbers.

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

Now, we will map over the array, and multiply each element by two.

const numbers = [1, 2, 3, 4, 5];
numbers.map(num => num * 2);

Assign the resulting array to a variable, and print it to the Console.

const numbers = [1, 2, 3, 4, 5];
const doubled = numbers.map(num => num * 2);
console.log(doubled);

Transforming Arrays into a List of Elements

In React, transforming arrays into lists of elements is nearly identical. You can build collections of elements and include them within a JSX container.

First, we will import React and ReactDOM.

import React from "react";
import ReactDOM from "react-dom";

Now, let’s create an array of list items. We will call the mapped array, listItems. Instead of doubling each number, we will wrap each number in a li tag.

import React from "react";
import ReactDOM from "react-dom";

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

const listItems = numbers.map(num => <li>{num}</li>);

Now, we can render the listItems to the DOM, within two ul tags.

import React from "react";
import ReactDOM from "react-dom";

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

const listItems = numbers.map(num => <li>{num}</li>);

ReactDOM.render(<ul>{listItems}</ul>, document.getElementById("root"));

You can now see the bullet point list of numbers on the page.

Basic List Component

Usually, you would render lists inside a component. We can refactor the previous example into a component, that accepts an array of numbers, and outputs a list of elements.

We will create a NumberList component, which has the numbers array as a prop. We will destructure the numbers array from props. Then, we will return the listItems, wrapped in an ul. We will render the NumberList to the DOM.

import React from "react";
import ReactDOM from "react-dom";

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

const NumberList = props => {
  const { numbers } = props;
  const listItems = numbers.map(num => <li>{num}</li>);
  return <ul>{listItems}</ul>;
};

ReactDOM.render(<NumberList numbers={numbers} />, document.getElementById("root"));

Key

In Chrome’s Console, We are given a warning that a key should be provided, for the list items. A “key” is a special string attribute, that you need to include when creating lists of elements.

Let’s assign a key to our list items, to fix the missing key issue.

import React from "react";
import ReactDOM from "react-dom";

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

const NumberList = props => {
  const { numbers } = props;
  const listItems = numbers.map(num => <li key={num.toString()}>{num}</li>);
  return <ul>{listItems}</ul>;
};

ReactDOM.render(<NumberList numbers={numbers} />, document.getElementById("root"));

The warning no longer appears in the Console.

Keys help React identify which items have changed, have been added, or have been removed. Keys should be given to the elements inside the array, in order to give the elements a stable identity.

Let’s say we have a list of Todo items. We will amend our numbers array to be a todos array. Each Todo item will be an object, with an id field, and a text field. We will add three example Todo items, our first being 'Learn React', with an id of '1'. Our second Todo will be 'Wash dishes' with an id of '2'. And, our third Todo will be 'Make bed' with an id of '3'.

import React from "react";
import ReactDOM from "react-dom";

const todos = [  {id: '1', text: 'Learn React'},  {id: '2', text: 'Wash dishes'},  {id: '3', text: 'Make bed'},];
const NumberList = props => {
  const { numbers } = props;
  const listItems = numbers.map(num => <li key={num.toString()}>{num}</li>);
  return <ul>{listItems}</ul>;
};

ReactDOM.render(<NumberList numbers={numbers} />, document.getElementById("root"));

Next, we will rename NumberList to TodoList. We will pass the todos as a prop. Our array item variable will be renamed from num to todo. We will render the text of the todo in our list item.

The best way to pick a key, is to use a string, that uniquely identifies a list item, among its siblings. In our example, we have a unique string id on each of our todo items.

import React from "react";
import ReactDOM from "react-dom";

const todos = [
  {id: '1', text: 'Learn React'},
  {id: '2', text: 'Wash dishes'},
  {id: '3', text: 'Make bed'},
];

const TodoList = props => {  const { todos } = props;  const listItems = todos.map(todo =><li key={todo.id}>{todo.text}</li>);  return <ul>{listItems}</ul>;
};

ReactDOM.render(<TodoList todos={todos} />, document.getElementById("root"));

We can now see our Todos on the page in the browser, with no warnings showing in the Console.

Use Index as a Last Resort

Let’s assume our todos had no ids, just text items in the array. When we don’t have stable ids for rendered items, we may use the item index as a key, as a last resort.

index is the second optional argument to the transformation function of the Array map method. Let’s not forget to remove the text property on the todo item.

import React from "react";
import ReactDOM from "react-dom";

const todos = [  'Learn React',  'Wash dishes',  'Make bed',];
const TodoList = props => {
  const { todos } = props;
  const listItems = todos.map((todo, index) => <li key={index}>{todo}</li>);  return <ul>{listItems}</ul>;
};

ReactDOM.render(<TodoList todos={todos} />, document.getElementById("root"));

Save the file, and we can see that there are no warnings appearing in the Console.

We don’t recommend using indexes for keys if the order of items may change. This can negatively impact performance and may cause issues with component state. If you choose not to assign an explicit key to list items, then React will default to using indexes as keys.

Summary

We demonstrated how to map over an array of elements and render them. We showed that a key is necessary when rendering a list of elements. And, we showed that if a stable and unique id is not available as a key, then we can use the array item index, as a last resort.

Next Up…

In the next video, we will continue to discuss rendering lists of elements and using keys.