Lesson #11 of 13 in Getting Started with React

Displaying Lists in React and JSX

Showing a list of items is crucial in every single application we'll build. Using JSX we can show lists using JavaScript's built-in Array.map() method.

The .map() is often used to take one piece of data and convert it to another. In our scenarios, we are taking data and converting it to a piece of our view.

Let's say we have a list of users that we want to show in a list:

jsx
function App() {
  const people = [
    { name: 'chris' },
    { name: 'nick' }
  ];

  return (
    <div>
      {people.map(person => (
        <p>{person.name}</p>
      ))}
    </div>
  );
}

When creating a list in JSX, React may show you an error and ask for a key.

React Error

Keys are unique identifiers that must be attached to the top-level element inside a map. Keys are used by React to know how to update a list whether adding, updating, or deleting items. This is part of how React is so fast with large lists. Read up on keys on the official React docs.

😄Tip
Keys are a way to help React know how to efficiently update a list.

We can add a key using the key prop like so:

jsx
<div>
  {people.map(person => (
    <p key={person.name}>{person.name}</p>
  ))}
</div>

Note: The key must be unique for each child.

The key must be unique for each item. Let's see a couple different ways we can make sure the key is unique.

If each item in your array has a unique identifier, then we can use that. In our above example, name is unique for each person, but this may not be the case in the future. If we had a [user.id](http://user.id) on each object, then that is something we could use.

jsx
function App() {
  const people = [
    { id: 1, name: 'chris' },
    { id: 2, name: 'nick' }
  ];

  return (
    <div>
      {people.map(person => (
        <p key={person.id}>{person.name}</p>
      ))}
    </div>
  );
}

If we don't have anything unique on each object, we can use something built into .map(). map can pass us a second value, which is the index. This is an auto incremented number (starting at 0) that will be unique within this map().

jsx
function App() {
  const people = [
    { name: 'chris' },
    { name: 'nick' }
  ];

  return (
    <div>
      {people.map((person, index) => (
        <p key={index}>{person.name}</p>
      ))}
    </div>
  );
}

Each index will be unique for each item in the map now!

For nested lists, we have the ability to create a map within a map. Make sure to name your variables with good detail so you know which data you are using.

Here's an example of a list of users that have pets.

jsx
function App() {
  const people = [
    { 
      name: 'chris',
      pets: [
        { name: 'bella', type: 'dog' },
        { name: 'cocoa', type: 'dog' }
      ]
    },
    { 
      name: 'nick',
      pets: [
        { name: 'hilo', type: 'cat' },
        { name: 'polly', type: 'cat' }
      ]
    }
  ];

  return (
    <div>
      {people.map((person, index) => (
        <div key={index}>
          <h2>{person.name}'s Pets</h2>

          {/* loop over the pets */}
          <div>
            {person.pets.map((pet, i) => (
              <p key={i}>
                {pet.type} named {pet.name}
              </p>
            ))}
          </div>
        </div>
      ))}
    </div>
  );
}

ReactDOM.render(<App />, document.getElementById('root'));

Array.map() only works on arrays. If we have an object that we want to loop over and display using JSX, we'll have to change our strategy a bit. Objects don't have a .map() method that we can take advantage of.

The main strategy is to create an Array using Object.keys() and use those keys to get values out of our object.

An example of why we would want this is to loop through all the properties in an object and display them. For example, let's take a person object and loop through the properties. We'll show it all in a list and that will be our "user profile" view.

We'll use Object.keys() to convert our Object into an Array that we can map over. For example, let's see what the following object would look like if we used Object.keys():

jsx
const person = {
  name: 'Chris',
  twitter: 'chris__sev',
  bio: 'The dude'
};

Object.keys(person); // Array ["name", "twitter", "bio"]

Now we can take each of those keys to get the value of each property. person['name'] will return Chris.

jsx
function App() {
  const person = {
    name: 'Chris',
    twitter: 'chris__sev',
    bio: 'The dude'
  };

  return (
    <div>
      {Object.keys(person).map(key => (
        <p>{person[key]}</p>
      ))}
    </div>
  );
}

All in all, we're creating an Array using Object.keys() and using those keys to get values out of our object.

We could even use the key as a label:

jsx
function App() {
  const person = {
    name: 'Chris',
    twitter: 'chris__sev',
    bio: 'The dude'
  };

  return (
    <div>
      {Object.keys(person).map(key => (
        <p>
          <strong>{key.charAt(0).toUpperCase() + key.slice(1)}: </strong>
          {person[key]}
        </p>
      ))}
    </div>
  );
}

These looping strategies are heavily used in our React applications. Always be sure to add a key when looping over things and you'll be in good shape!

Chris Sev

Chris Sev

Chris Sev is the co-founder of Better Dev. Coding better every day. Previously he created Scotch.io which was acquired.

Comments

What did you think of the article? Let us know!
(these comments are powered by GitHub issues and use 0 trackers)