Lists and Loops in React

Lists of elements

If there’s one unchanging thing about web applications, it’s that they have lists. And so as you might expect, most frameworks attempt to make your life easier with a special syntax for lists.

But with React, elements are just objects, React.createElement() is just a function, and lists are… actually, what do you think lists are?

Think about it for a minute. Once you’ve got an answer, check it by clicking below.

Lists are just arrays of element objects!

#To render a list…

Rendering a list with React involves three steps:

  1. Create an array of element objects
  2. Set that array as the children of a container element
  3. Render the container element

For example, let’s say you want to render a list of 10 div element, styled as a spiral.

To accomplish this, you might create an array of styled div elements with a for loop, and render that list inside a div parent:

index.js
getSpiralStyle.js
import React from 'react'
import ReactDOM from 'react-dom'
import { getSpiralStyle } from './getSpiralStyle.js'

let boxElements = []
for (let i = 0; i < 10; i++) {
  let style = getSpiralStyle(i, 100, 50*Math.PI/180)
  let boxElement = React.createElement('div', { style }, i)
  boxElements.push(boxElement)
}

let containerElement = React.createElement('div', {}, boxElements)

ReactDOM.render(
  containerElement,
  document.getElementById('root')
)
Build In Progress

#A real-world list

Let’s say you’ve got an array of billionare’s contact details. Naturally, the first thing you’ll want to do with it is create a React app to display it.

let billionaires = [
  { name: 'Bill Gates', email: 'billg@microsoft.com' },
  { name: 'Jeff Bezos', email: 'jeff@amazon.com' },
  { name: 'Mark Zuckerberg', email: 'zuck@fb.com' },
]

Lucky for you, you’ve been following along and doing the exercises (right?), and so you’ve already built a styled contact list — which I’ve started you off with below.

Your task is to render one contact item element for each of your friends in the billionaires array.

You can build the array with a for loop or with array.map — whichever you’re most comfortable with.

Also, if you get a warning in the console about “key” props, don’t worry - we’ll cover that soon!

index.js
styles.css
import React from 'react'
import ReactDOM from 'react-dom'
import './styles.css'

let billionaires = [
  { name: 'Bill Gates', email: 'billg@microsoft.com' },
  { name: 'Jeff Bezos', email: 'jeff@amazon.com' },
  { name: 'Mark Zuckerberg', email: 'zuck@fb.com' },
]

// Your React elements will go here.
let elements = [
  <div className='Contact'>
    <div className='Contact-avatar'>JN</div>
    <span className='Contact-name'>James Nelson</span>
    <a href='mailto:james@frontarm.com'>
      james@frontarm.com
    </a>
  </div>
]

// Use a for loop or array.map to build the elements array

ReactDOM.render(
  <div className='ContactList'>{elements}</div>,
  document.getElementById('root')
)
Build In Progress

If you’ve given the exercise a decent crack, and would like to check your answer against mine, then go ahead! Just click the Solution button at the bottom of the editor.

Also, why not add your own name to the list. Just for kicks.

#The key prop

Once you’ve got the above example working, try opening up the console (by clicking on the “console” icon at the bottom of the editor). You should see this warning:

Warning: Each child in an array or iterator should have a unique “key” prop. Check the top-level render call using <ul>. See https://fb.me/react-warning-keys for more information. in li

So it turns out that I neglected to mention something: you’ll need to add a unique key prop to each element in your array. If you don’t, things usually work. But to be sure, let’s add a key based on the position within the list:

index.js
styles.css
import React from 'react'
import ReactDOM from 'react-dom'
import './styles.css'

let billionaires = [
  { name: 'Bill Gates', email: 'billg@microsoft.com' },
  { name: 'Jeff Bezos', email: 'jeff@amazon.com' },
  { name: 'Mark Zuckerberg', email: 'zuck@fb.com' },
]

// Your React elements will go here.
let elements = []
for (let i = 0; i < billionaires.length; i++) {
  let contact = billionaires[i]
  let names = contact.name.split(' ')
  let initials = names.map(name => name[0].toUpperCase()).join('')
  let element =
    <div className='Contact' key={i}>
      <div className='Contact-avatar'>{initials}</div>
      <span className='Contact-name'>{contact.name}</span>
      <a href={'mailto:'+contact.email}>
        {contact.email}
      </a>
    </div>
  elements.push(element)
}

ReactDOM.render(
  <div className='ContactList'>{elements}</div>,
  document.getElementById('root')
)
Build In Progress

    Notice how adding a unique key to each element in an array fixes the warning? I’ll explain why the key prop is needed in greater detail later on. But first, let’s add some pictures!

    Progress to next section.