Getting Started with React: Lesson 8 of 14

Iterating Over Data

Up Next

Passing Props Through Children

Autoplaying in 7 seconds!

Cancel

Now that we have the weather data being stored in our App component's state, we need to display each of the days and their high and low temperatures for each day. We have each day's data stored in an array of objects. We need some way to iterate over this array and then display the data for each of those days. We should also try to encapsulate this logic somewhow so that the App component doesn't need to know how to display them. Luckily, by using components and JSX, this is simple!

First, we will create a component that will receive the array of weather data. This component will be in charge of displaying each day. Create a new file at src/components/WeatherList.js and put the following in it.

import React, { Component } from 'react';

class WeatherList extends Component {

  render() {
    const { days } = this.props;

    return (
      <div className="weather-list flex-parent">
      </div>
    );
  }
}

export default WeatherList;

This is just a basic outline of our component. Now, we need another component that can hold all the logic for displaying just a single day. Make a new file at src/components/WeatherListItem.js and put the following in it.

import React, { Component } from 'react';

class WeatherListItem extends Component {
  render() {
    const { day } = this.props;
    const date = new Date(day.dt * 1000);

    return (
      <div className="weather-list-item">
        <h1>{date.getMonth() + 1} / {date.getDate()}</h1>
        <h2>{day.temp.min.toFixed(1)}&deg;F &#124; {day.temp.max.toFixed(1)}&deg;F</h2>
      </div>
    );
  }
}

export default WeatherListItem;

In our render method, we are pulling a day object out of props. We will need to make sure the day is passed from the parent. We are then doing some calculations to get the correct numbers to display, and then we are returning a div containing this information.

Now, there's something you need to know about React. A render method can only return one component. This is why everything is wrapped in a div. However, if you have an array of components inside a render method somewhere, React will put every component in that array onto the DOM. We can take advantage of this when displaying lists of data.

We want to take an array of day data and get an array of WeatherListItem components that each have been passed a piece of day data. JavaScript has a built in array method for just this use case: map! Map will transform one array into another according to a function that we define. Add the below code inside our WeatherList.

{days.map((day) =>
  <WeatherListItem
    key={day.dt}
    day={day}
  />
)}

We have called map on our days array. We are using an arrow function, which has implicit return, as our callback. We are returning a WeatherListItem component that is passed two props: key and day. day is the one we specified in the WeatherListItem earlier. key is a special prop used by React to make sure it can reliably track which piece of data needs to be updated when it is calculating the virtual DOM internally.

Make sure to import the WeatherListItem component into WeatherList.

import WeatherListItem from './WeatherListItem';

Let's get something on the page by importing the WeatherList into our App and putting one in its render method.

import WeatherList from './WeatherList';

...

  render() {
    const { dates } = this.state;

    return (
      <div className="app">
        <ZipForm onSubmit={this.onFormSubmit} />
        <WeatherList days={dates} />
      </div>
    );
  }

Notice how we are pulling dates out of state and passing it as the days prop to our WeatherList component.

In the next one, we will update these components so that when we click on one, we save which one was clicked on in the App.

Alex Sears

Developing is not only my job but also my passion. I love to teach myself new things as much as I love teaching others. The more people we get involved in this little thing we call "web development," the better we can make it. I mean, we always need more cat videos, right?