Iterating through JSON data in React

Note: I am not an experienced React developer, it is my 2018 project to teach myself React and to blog as I do, so that I learn exactly what is happening and why (see this post for why). If there are any errors in this post or you believe there is a better way to do something please leave a comment and let me know 🙂

Warning: This article assumes you already understand dealing with arrays in Javascript and using API’s. See additional reading notes at the end of the article is you feel you need more information on these topics.


One of the things I’ve been struggling to get my head around in React is passing data down through components easily. When I talk about this, I don’t mean setting a single value in state and passing it down to the relevant component through props, I mean fetching data from a third party API, and looping through it to show results.

For example:

Looking at this endpoint from the Github API: https://api.github.com/repos/Automattic/_s/issues
(I like to use Postman to view results from an API call rather than curl in the command line – It is an API development environment, so can be used for much more, but I like how it saves my history).

When we fetch this in React it returns an object full of JSON data that we then set as state (Fetching data from an API is an entire topic on its own, see further info at the bottom for an excellent video from Jack Franklin on how to do this). We can then pass this state down to our child component using props.

In App.js we would have:

<IssuesTable githubData={this.state.githubData}/>
// this.state.githubData being the JSON data we set as state

In our child component we would then receive the data as Props from within our render method.

In ChildComponent.js we would have:

class IssuesTable extends Component {
   render() {
      const { githubData } = this.props;
      return ();
   }
}

* Note: const { githubData } = this.props;  is using the new ES6 destructuring syntax. See notes at the end for more information.

Our data, original saved as state, now passed as Props

If we take a look at the React panel in Chrome DevTools, we can see that our data is now being passed down to our child component as Props.

So far so good…

When we look at what is being passed down though, it becomes clear pretty quickly that in order to display this data in a tabular way, we are going to have to loop through and output each array item as a table row.

At this point you would be forgiven for thinking that you could loop through the data and output each row using either a for or foreach loop. But before we can do that we first have to assign keys to the data so that we could access it within our loop. To start with I thought this would be a simple case of using the .map() function to assign each row its own key. something similar to this:

{githubData.map((gh, i)=>(
   <li key={i}>
      {gh.title}
   </li>
 ))}

WRONG!
I kept hitting this error:

TypeError: githubData.map is not a function

This is because, although Chrome Dev Tools lists the data in Props as an array, at the moment it is still an object containing JSON data (this took me quite a while to realise) and therefore the map function will not work yet.

Enter Object.keys()

What this does is, return an array of data where the elements keys are all strings that match the data within the JSON object. For example:

let user = {
   name: kirsty
   age: nevermind
}

Would be Object.keys(user) = [name, age].

Looking at the data in githubData, the Object.keys would be all of the items shown inside githubData[0] above.

So now we have access to the data, all that is left is to loop through it so that we can create a table of github issues. And to do that we would combine Object.keys() and .map() and pass the information we need to a new component via props like this:

{Object.keys(githubData).map(key => (
   <Issue key={key} details={githubData[key]} />
))}

It looks like there is a lot going on here but if we break it down, we are first taking the Props githubData and creating keys that are strings matching the data within. For example keys would now include title, state, url etc.

The .map()function then creates a new array with these strings as the keys and then for each key that exists, loops through and assigns the key and value to the props key and details for use inside the <Issue /> child component.

We could then display the data inside the <Issue /> component like this:

class Issue extends Component {
   render() {
      // details is all the githubdata coming from the details prop above
      const { details } = this.props;

      return (
         {details.title}
      ); 
   } 
}

Magic! 🙂

Further Reading

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

w

Connecting to %s

Blog at WordPress.com.

Up ↑

%d bloggers like this: