React & REST API: How to render responses
Tags: react, javascript, node, tutorial
Published: 2021-03-15 08:01:38

---
published: true
title: React & REST API: How to render responses
description: Learn how to call REST APIs from a React App and render the response
series: React & REST API
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0owgvn2290szgfyrypt2.png
tags: react, javascript, node, tutorial
---

# <u>Overview</u>
This series will walk through how to make REST API calls from a React component to a 3rd party service, and render the result into the UI.

Our core focus will be on making the call, so we'll keep the rendering process very simple in this series (i.e. no tables, no colors, just displaying the plain JSON response).

## The final image

Our React project will use an Express server as a proxy, so that it will make REST API calls to our desired service. The response from the service will be routed through our Express server back to our React project, where it will be rendered into the UI.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/oomzkx3uergdnbobi32t.png)

## The directory structure

The final directory tree looks roughly like this.

```
.
└── myproject/
    ├── frontend/
    │   ├── index.js
    │   └── index.html
    └── backend/
        ├── server.js
        └── .env
```

I say "roughly", because technically more files actually exist in this project, and some files shown above exist a bit deeper in the tree. I just wanted to make it clear that these will be the main files in the project.

OK, so let's start ٩( 'ω' )و

# <u>Set up a Node environment</u>

## Create a directory to work in
We'll start off by creating a directory to place our frontend and backend projects in, and move to that directory.

```
mkdir myproject
cd myproject
```
If you're using Visual Studio Code, you can enter the following into the terminal to open up your project in the editor which makes managing the project easier.

```
code .
```

## Install Node
Install Node into this directory.
Since we'll be using react, Node needs to be version 10.16 or later. It's up to you on how you install Node - I personally like using [nodenv](https://github.com/nodenv/nodenv) to manage my node projects.

```
nodenv local 14.5.0
```

Great, now that we have that set up, let's carry on!

# <u>Set up a React App</u>

## Create React App

We'll use [create-react-app](https://reactjs.org/docs/create-a-new-react-app.html) to build our React application simply and quickly. Run the following command in the **myproject** directory.

```
npx create-react-app frontend
```
This may take a few minutes, but in our **myproject** directory we should end up with a directory named **frontend**, with a whole lot of files inside.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nfxp986n4hqz4q186r99.png)

## Run the App
Move into the newly created directory and start the React App.

```
cd frontend
npm start
```
If your browser has started to run and is showing the screen below, we're ready to move on. If not, access `http://localhost:3000/` to view this page. Make a note that this project will be running on port 3000.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e7fyoof1nvmspyxwvd00.png)

## Delete unnecessary files

Since our objective in this article isn't focused on making fancy looking applications, let's delete everything in our src directory except for the **index.js** file.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jg8vikl7cxpyi6fo3eu8.png)


## Run some React code

Open up **index.js** in the editor and delete every line of code in there, so we can start from scratch. Let's run a simple code that uses React to render content into the UI. 

```javascript
import React from 'react';
import ReactDOM from 'react-dom';

const myelement = <h1><u>These are the details of the myelement const</u></h1>;

ReactDOM.render(
    myelement,
    document.querySelector('#root')
);
```

Refresh the browser running the react App, and we should get this.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5397y3nfebstnq0s2u8m.png)

So far so good - now our next step is to start working on API calls.



# <u>Make REST API calls to Random User Generator API</u>
## Random User Generator API
Random User Generator API is an API service that generates random fake user information - a quick and easy place to test out REST API calls from our React project.

## Fetch data from Random User Generator API
We'll first make our API call to the following endpoint: `https://randomuser.me/api/`

We'll add in a function to make a REST API call to this endpoint, and we'll display the result in the console.

```javascript
import React from 'react';
import ReactDOM from 'react-dom';

//-----Added in code from here-------
const restEndpoint = "https://randomuser.me/api/";

const callRestApi = async () => {
    const response = await fetch(restEndpoint);
    const jsonResponse = await response.json();
    console.log(jsonResponse);
};

callRestApi();
//--------------to here---------------

const myelement = <h1><u>These are the details of the myelement const</u></h1>;

ReactDOM.render(
    myelement,
    document.querySelector('#root')
);
```

Reload your browser running the React App, and you should see this in your console.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jovanw3jrlh150dapmuu.png)

By making a request to the `https://randomuser.me/api/` endpoint, we're given back data of a random user. Every time we refresh the browser, we should see new information of a random user being displayed in the console.

Now since we're using React, let's try rendering the result into the browser UI.

## Render the response
So we should be able to render the result if we were to pass the result into `ReactDOM.render()`, right? Let's update our code so that the first parameter of this method will call our `callRestApi` function. We'll adjust our `callRestApi` function to return a React element by using [React.createElement](https://reactjs.org/docs/react-api.html#createelement), with our third parameter being a stringified version of our REST API response. We'll also remove any unused functions and variables.

```javascript
import React from 'react';
import ReactDOM from 'react-dom';

const restEndpoint = "https://randomuser.me/api/";

const callRestApi = async () => {
    const response = await fetch(restEndpoint);
    const jsonResponse = await response.json();
    console.log(jsonResponse);
    return React.createElement('h1', null, JSON.stringify(jsonResponse));
};

ReactDOM.render(
    callRestApi(),
    document.querySelector('#root')
);
```

So this *should* in theory get the REST API response, and then render the result into the root element. Let's see the result.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fqzq8zqdzqre7ox5cfen.png)

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ms5xeaygvqkgz09fra7s.jpg)

*Objects are not valid as a React child (found: [object Promise])* ... Whaaaaat...?

So let's see what went wrong.

`ReactDOM.render()` calls the `callRestApi()` function to obtain the element to render on the root.

```javascript
ReactDOM.render(
    callRestApi(),
    document.querySelector('#root')
);
```

As `callRestApi()` is an async function, it immediately returns a promise object while it goes off to make the REST API call. 

```javascript
const callRestApi = async () => {
    //...
};
```

REST API calls are not instant. Because there's a server on the other end processing the request, it takes time for the result to be responded back. React doesn't "wait" for the REST API result to come back though when it's told to render an element - this results in `ReactDOM.render()` trying to render this pending promise object immediately, and failing.

So what do we do?

For React to take care of REST API calls, we need to use the **useState Hooks** and **useEffect Hooks** in our code.

For those who are unfamiliar with these notations:
- [useState hooks](https://reactjs.org/docs/hooks-state.html) allow us to use special "state" variables that we can utilize to render into the React UI.
- [useEffect hooks](https://reactjs.org/docs/hooks-effect.html) allow us to run functions after rendering has finished. We'll use this to run a REST API call and update the state variable, which will then cause React to *re-render* the UI with the new state variable.

```javascript
import React, { useState, useEffect } from 'react';
import ReactDOM from 'react-dom';

const restEndpoint = "https://randomuser.me/api/";

const callRestApi = async () => {
    const response = await fetch(restEndpoint);
    const jsonResponse = await response.json();
    console.log(jsonResponse);
    return JSON.stringify(jsonResponse);
};

function RenderResult() {
  const [apiResponse, setApiResponse] = useState("*** now loading ***");
  
  useEffect(() => {
      callRestApi().then(
          result => setApiResponse(result));
  },[]);

  return(
      <div>
          <h1>React App</h1>
          <p>{apiResponse}</p>
      </div>
  );
};

ReactDOM.render(
    <RenderResult/>,
    document.querySelector('#root')
);
```

Running this should give us the following result, with data of a random user displayed. We can reload the page to display datasets of other random users.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s4hy00cysrqc0a8n2jkf.gif)

Great!

You'll notice there's a lag before the user data is displayed on the UI. This lag is caused by the REST API call which takes a bit of time to get the response back from the server it's requesting to. The UI will not re-render until the code retrieves the response.

We won't go into too much details about what each hook related statement does, as it's probably easier to understand through the React docs. But here is an overview of what we are doing.

Our initial state value is the string "*** now loading ***", which is displayed in the UI due to the initial rendering.

```javascript
const [apiResponse, setApiResponse] = useState("*** now loading ***");
```

After the rendering finishes, `useEffect()` runs the REST API call, waits for the response to come back (which is causing the lag), then updates the state variable with the new response. 

```javascript
useEffect(() => {
    callRestApi().then(
        result => setApiResponse(result));
},[]);
```

React automatically re-renders the UI whenever there's a state change, and thus updates the UI with the response from the REST API call. The second argument of `useEffect()` controls when the re-rendering should be done - in this case, we passed in an empty array so that the re-rendering is only invoked once.

# <u>Next steps</u>

In this article, we've gone through methods on how to make REST API calls to a REST endpoint from a React component, and render it into the UI.

In part 2 of this series, we'll run into common issues that developers run into when trying to call other REST endpoints.

                       ＿人人人人人人人＿
                       ＞ CORS ERRORS ＜
                       ￣Y^Y^Y^Y^Y^Y^￣
                       (\__/) 
                       (•ㅅ•) 
                       /つ つ