Loading and Using External Data in React

Avatar of Chris Coyier
Chris Coyier on (Updated on )

Hey JavaScripters! I’ve been learning a bunch about React lately. It’s very fun. It feels like a great way to write JavaScript. Seems to me it has almost the same feel jQuery did in the early days.

Confession though: I’m not master of it. I’m about to show you how to do something in React, without being a CertifiedSuperReactPro®. It works though, so something is going right.

These days you’d probably use function comnponents in React, and use a hook to fetch the data, which is like the modern way to handle a “side effect” of a component, which is a modern improvement over lifecycle methods. So this article is old in that sense. Conceptually it still makes sense though. I’ll update little bits of it with more modern stuff where I can.

State, State, State

One of the first things you learn in working with React is state. It’s pretty fundamental to React. It’s essentially data, and it could be anything!

Imagine the comments section of a website. Some of the “state” might be:

  • Is the comment form visible or not?
  • Is the “Submit Comment” button disabled or not?
  • The current value of the textarea, so it can be used in the comment preview area

But the state is also:

  • All the existing comments!

It makes sense, I think. Comments are part of different articles – they are different on every page. They are part of the data of that page. They are state.

// Just the state part of creating a React component
var Comments = React.createClass({

  getInitialState: function() {
    return {
      commentForm: {
        visible: true,
        submitVisible: false
      }
      comments: {
        unique-id-1: {
          name: "Chris Coyier",
          comment: "Lorem ipsum..."
        },
        unique-id-2: {
          name: "Sammy Sanddollar",
          comment: "Lorem ipsum..."
        }
      }
    }
  }

});

Building a mock “comment for” is exactly one of the exercises I used to help learn React. I have a video of me pairing with Sarah Drasner to do that you can watch.

Grabbing that data

In the case of comments, you likely have that data in your own app.

But data doesn’t have to come from yourself, data can come from anywhere. External data, if you will. Like from an API.

Ajax

Since we’re working entirely on the front end here, grabbing data from an API is Ajax territory. I don’t know about you, but I think of Ajax like this:

// jQuery!
$.ajax {
  url: "https://api.com/whatever"
}.then(function(data) {

});

But as I just learned in a recent article, jQuery isn’t exactly BFF’s with React. jQuery is mostly a DOM manipulation library, and React has its own way of doing those things. The Ajax stuff that jQuery provides is convenient, but replicable by other more focused libraries.

Axios is a library like that with an identical API.

Example Data

Let’s use some simple, publicly available JSON:

https://codepen.io/jobs.json

It’s simply a chunk of data that describes all the job postings on the CodePen Job Board.

Requesting the Data

In Axios, requesting that data is like:

axios
  .get("https://codepen.io/jobs.json")
  .then(function(result) {    
    // we got it!
  });

With a React Hook, we’d it like this…

import React, { useState, useEffect } from 'react';
import axios from 'axios';

function App() {
  const [data, setData] = useState({ jobs: [] });
  useEffect(async () => {
    const result = await axios(
      'https://codepen.io/jobs.json',
    );
    setData(result.data);
  });
  return (
     <p>Loop over jobs data here and show results.</p>
  );
}
export default App;

Setting the State with External Data

Now that we have the data, let’s make it available to our app by setting the state in React. The result is the chunk of JSON. The main bit of that is an array of job, exactly what our data setup is expecting. We use setState:

var App = React.createClass({

  getInitialState: function() {
    return {
      jobs: []
    }
  },

  componentDidMount: function() {
    var _this = this;
    this.serverRequest = 
      axios
        .get("http://codepen.io/jobs.json")
        .then(function(result) {    
          _this.setState({
            jobs: result.data.jobs
          });
        })
  },

  componentWillUnmount: function() {
    this.serverRequest.abort();
  },

  render: function() {
    return (
      <div>
        {/* Render stuff here */}
      </div>
    )
  }
});

There is a little bit of error handling here. If the Ajax request is still going when React (or you) decides to remove a component, the Ajax request will be aborted.

Also, make sure to render the component!

React.render(<App />, document.querySelector("#root"));

Templating the Data

You don’t need any additional libraries to do templating in React. HTML templating is a pretty fundamental part of React, especially if you write in JSX (that stuff that looks like HTML in JavaScript), which is highly recommended.

If we wrote HTML all by ourselves to represent a single job, it would be like this:

<div class="job">
  <a href="http://link-to-job.com">
    Company
    is looking for a 
    Full Time
    Web Designer
  </a>
</div>

I like thinking in that way: consider the HTML you want, then move that HTML over to JSX and replace the dynamic parts with state.

That becomes:

var App = React.createClass({

  getInitialState: function() {
    // ...
  },

  componentDidMount: function() {
    // ...
  },

  componentWillUnmount: function() {
    // ...
  },

  render: function() {
    return (
      <div>
        <h1>Jobs!</h1>
        {this.state.jobs.map(function(job) {
          return (
            <div key={job.id} className="job">
              
                {job.company_name}
                is looking for a 
                {job.term}
                {job.title}
              
            </div>
          );
        })}
      </div>
    )
  }
});

Demo

With all that together, we got ourselves a nice little React component that renders itself with external data!

See the Pen
Load External Data in React
by Chris Coyier (@chriscoyier)
on CodePen.


This dovetails into all the React stuff swirling in my head, like our recent series, recent video, and recent discussion on headless CMSs.