Get Started with Modern React: Step by Step
S02・V14: Lists and Keys (Part 1)
- We will demonstrate how to map over an array of elements and render them.
- We will show that a key is necessary when rendering a list of elements.
- 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.
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 id
s, just text items in the array. When we don’t have stable id
s 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.