Day to Day React: Api Integration

05.16.2022

Intro

Recently while teaching, I started to compile a list of "day to day" activities that a React developer would do. One common activity is integrating a component with an api. This consists of making a request to an external api and displaying the data. As a bonus, I would add a element to interact and change parameters sending to this api.

With this in mind, this article will cover a simple step by step plan that can be repeated to practice this daily activity in preparation for working as a React Developer.

Getting the Api

The first step is to select an api and preview it's contents.

To select an api for practice, I'd recommend this list of public apis on Github.

https://github.com/public-api-lists/public-api-lists

github public api

Previewing the Api

The next step is to preview the api. For this example, we will use the Meowfacts api: https://github.com/wh-iterabb-it/meowfacts.

When previewing the api, we can make GET requests in our browser or use something like Hopscotch.io or Postman. (I use hopscotch since it is open source).

From the github page, there is one link: https://meowfacts.herokuapp.com/, so opening that in the browser, we can see the following.

browser meowfacts

And in Hopscotch, we make a GET request as well.

hopscotch meowfacts

Setting up React

If you don't have a react app set up already, let's create one. In your normal work environment, this will be created for you usually.

npx create-react-app api-example

Now install and start the app.

cd api-example
npm start

Hardcode the Response

The order doesn't necessarily matter, but for the next step I like to add a hard coded response then mock up the UI around it. Pulling from Hopscotch, we can use the following as an example response.

{
  "data": [
    "There are cats who have survived falls from over 32 stories (320 meters) onto concrete."
  ]
}

Open up a component. If you are following along, open up App.js. Let's add the response as a hard coded variable inside the App component. I also removed some of the boilerplate html.

function App() {
  const catResponse = {
    data: [
      "There are cats who have survived falls from over 32 stories (320 meters) onto concrete."
    ]
  }
  
  return (
    <div className="App">

    </div>
  );
}

Now we can use the variable to render the response. For this we can just use a simple un ordered list element. We will also use a React code block {} to interpolate our variable into the html.

function App() {
  const catResponse = {
    data: [
      "There are cats who have survived falls from over 32 stories (320 meters) onto concrete."
    ]
  }
  
  return (
    <div className="App">
      <ul>
        <li>{catResponse.data[0]}</li>
      </ul>
    </div>
  );
}

This is good so far, but let's take it one step further. The data property is an array, so we can expect more facts to be in that array. Because of that, let's convert our html to use map to render our lists. Note that I leave the verbose syntax to be a little easier for newer js devs to read.

function App() {
  const catResponse = {
    data: [
      "There are cats who have survived falls from over 32 stories (320 meters) onto concrete."
    ]
  }
  
  return (
    <div className="App">
      <ul>
        {catResponse.data.map((fact) => {
          return (
            <li>{fact}</li>
          )
        })}
      </ul>
    </div>
  );
}

Convert The Response to State

Now that we are rendering the response, we want to convert this to a state variable. In the end, we will make a request and update our variable. To do this, we need to add in the useState hook.

The new line of code is this:

const [catResponse, setCatReaspon] = useState({})

Here we call React's useState function and pass an empty object as our initial state. UseState will return an array with the first item being the state and the second being a function to change the state. So catResponse will be empty.

To make this slightly better, we can use our hard coded response as the initial state. We can move the response out of the component and rename it initialState than pass it to the useState function. Then, when a user loads the page, they will see a fact while they wait for the api call. The final code looks like this.

import { useState } from 'react';
import './App.css';

const initialCatResponse = {
  data: [
    "There are cats who have survived falls from over 32 stories (320 meters) onto concrete."
  ]
}

function App() {
  const [catResponse, setCatResponse] = useState(initialCatResponse)
  
  return (
    <div className="App">
      <ul>
        {catResponse.data.map((fact) => {
          return (
            <li>{fact}</li>
          )
        })}
      </ul>
    </div>
  );
}

export default App;

Make the Api Call

We can now move on to making the api request. For this, we will use the fetch api. The following is the function we will use for making the GET request to MeowFacts. Read more on the fetch api here if you are not familiar: https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch.

async function getMeowFacts() {
  const response = await fetch('https://meowfacts.herokuapp.com/')
  const data = await response.json()
  return data;
}

Update the State

And finally, we can now get the response and update our state. To do this, we will use the useEffect hook which allows for "side effects" in our app. It is commonly used on Component render to load api data. Some examples in w3schools are a nice explanation: https://www.w3schools.com/react/react_useeffect.asp.

We will use useEffect with no dependencies for now to do a one time load and call our getMeowFacts function. We also await the promise using then syntax as React recommends useEffect to be synchronous. Finally, we call the setCatReason method from useState to update our response. The following is the result.

useEffect(() => {
    getMeowFacts().then((meowFactData) => {
      setCatReason(meowFactData)
    })
  }, [])

The final code

The final code is the following which will be a familiar setup in your day to day React development.

import { useState, useEffect } from 'react';
import './App.css';

const initialCatResponse = {
  data: [
    "There are cats who have survived falls from over 32 stories (320 meters) onto concrete."
  ]
}

async function getMeowFacts() {
  const response = await fetch('https://meowfacts.herokuapp.com/')
  const data = await response.json()
  return data;
}

function App() {
  const [catResponse, setCatReason] = useState(initialCatResponse)

  useEffect(() => {
    getMeowFacts().then((meowFactData) => {
      setCatReason(meowFactData)
    })
  }, [])

  
  return (
    <div className="App">
      <h1>Meow Facts</h1>
      <ul>
        {catResponse.data.map((fact) => {
          return (
            <li>{fact}</li>
          )
        })}
      </ul>
    </div>
  );
}

export default App;

meow facts app

The web page looks pretty bare bones, but styling is a separate article.