Learn how to use React Suspense for data fetching (part 2)
Tags: javascript, webdev, react, suspenseapi
Published: 2022-08-13 12:49:00

Hello 👋,

In the first part, we explained React Suspense APi, what it does and how it works in conjunction with lazy components.

In this last part, we will see how to use React Suspense when it comes to fetching data. While waiting for the response to be available, the user needs to see something on his screen and React Suspense does it better, by providing a fallback that displays something on the screen to let the user know that there is a process loading in the background.

**Prerequisites**

- 
If you didn't read the first part of this series [click here](https://dev.to/derick1530/reactsuspense-for-data-fetching-part-1-4a0h) to read it.

- 
A basic understanding of JSON server, i have an article that will give you a better understanding of the concept with some examples.
you can read it here

- 
 The code for this article can be found [ here](https://github.com/Derick1530/suspense-api-fici-game/tree/part2).

First, you need to clone the repo in your local machine,
next, Open the repo in your text editor (in my case I'm using `VScode`).
We have two folders:  `web-client` and `server`.
Open up your terminal inside vscode: `Control + J` for windows users and `Command + J` for mac users.
you should be in this directory:

![Folder Structure](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2ukov38iciyehzj4u4y9.png)
add a second terminal
![Two terminals](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ej6o9it5km9ape6g3tbf.png)
To install all the dependencies, in the first terminal navigate to `web-client directory` then run `npm install`, and do the same in the `server directory` but do it in a second terminal.

When all the dependencies are installed, in the `server directory `run the command `npm run serve-json`, a` port 7000` will be running on your machine and `npm run dev` in web-client. Next go to `localhost:3000` in your browser to access the website.

![Running the servers](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/l9sk1pqdp7j2qjj15347.png)
Now let's fetch data from the fake REST API which is running on our `localhost:7000/data.`

to do that let's create a new file inside web-`client/src/page/FiciGame/`
name it `fetchFici.js`

past the code below inside:

```javascript
const fetchFici = (search) => {
    return fetch(`http://localhost:7000/data?q=${search}`)
        .then(res => res.json())
        .catch(err => console.log(err))
}

const wrapPromise = (promise) => {
    let status = 'pending';
    let result = '';
    let suspender = promise.then(
        r => {
            status = 'success';
            result = r;
        },
        e => {
            status = 'error';
            result = e;
        }
    );
    return {
        read() {
            if (status === 'pending') {
                throw suspender;
            } else if (status === 'error') {
                throw result;
            }
            return result;
        }
    }
}

export const createResource = (search) => {
    return {
        data: wrapPromise(fetchFici(search))
    }
}

```
**Illumination:**

the first function fetchFici fetches data according to the parameter passed in. 
`http://localhost:7000/data?q={<params>}.`

To have this work we are going to create a function that going to take a promise as a parameter, inside we create a string variable called status with `'pending'` as a default value. This will keep track of whether a promise is completed or whether is loading or got an error.
The next line is a variable that going to wait for the promise.

At the bottom, we return a function that is going to read and check the status.
React Suspense expects us to throw a promise so it can catch it.

Last we export a function that returns an object, inside that object we passe `fetchFici()` which is going to return a promise that we are wrapping inside wrapPromise making sure it fits the Suspense API.

Once we have this setup we can reuse it.

```javascript
import React, { Suspense, useState } from 'react'
import Spinner from '../../layout/spinner';
import { createResource } from './fetchFici';
const FiciGame = () => {
    const [fici, setFici] = useState('Fire')
    const resource = createResource(fici);

    return (
        <div className='border rounded-md bg-zinc-800 border-white p-4'>
            <p className='text-center text-3xl font-mono'>Fici Game</p>
            <Suspense fallback={<Spinner />}>
             //Component to be add
            </Suspense>
            <ul className='flex justify-center gap-2 items-center'>
                <li onClick={() => setFici('Fire')} className='p-4 border hover:cursor-pointer text-2xl shadow-lg  bg-gray-900 border-white'>Fire</li>
                <li onClick={() => setFici('Rock')} className='p-4 border hover:cursor-pointer text-2xl shadow-lg  bg-gray-900 border-white'>Rock</li>
                <li onClick={() => setFici('Water')} className='p-4 border hover:cursor-pointer text-2xl shadow-lg  bg-gray-900 border-white'>Water</li>
                <li onClick={() => setFici('Air')} className='p-4 border hover:cursor-pointer text-2xl shadow-lg  bg-gray-900 border-white'>Air</li>
            </ul>
        </div>
    )
}

export default FiciGame
```
**Illumination:**

Inside `index.jsx` we create a useState that takes a string value.
We then set the value according to the `<li>` tag that will be pressed. 

then we `import creacteRessource()` which we save in resource, inside we pass the string got from fici.

Next, we import suspense component from React, we pass a fallback function which will be displayed while the data are fetching in the background. 
Inside the Suspense api we are going to create a component (i called it Screen) that will render after the process is done.

Now let's create that component.
Inside `web-client/src/page/FiciGame/` create a file called `screen.jsx`, inside that file type this code:

```javascript
import React from 'react'

const Screen = (props) => {
    const { resource } = props;
    const ficiData = resource.data.read()
    const ficiName = ficiData[0].name
    const ficiSymbol = ficiData[0].symbol

    return (
        <div className='border bg-gray-900 flex flex-col space-y-4 justify-center items-center border-white h-80 m-4'>
            <p className="p-4 font-mono text-lg">{ficiName}</p>
            <span className='text-9xl shadow-2xl rounded-full'>{ficiSymbol}</span>
        </div>
    )
}

export default Screen
```
We are calling `ressource.data.read()`; if it still loading, it will throw a promise which is going to be caught by suspense component and it's going to display a loading indicator otherwise we got our data and display it.

Go back to `index.jsx` and import Screen.jsx and place it inside Suspense component then save all your files.

```javascript
import Screen from './screen';

const FiciGame = () => {
    return (
[...]
            <Suspense fallback={<Spinner />}>
                <Screen resource={resource} />
            </Suspense>
[...]
    )
}

export default FiciGame
```
**Test**

> To test this, go to your browser open up your devtool in the network tab, on the top navigate to network and select "No throttling" choose fast 3G then refresh the page.
![Testing](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ehhyy3m3ss2kiudv6hq6.gif) 

Congratulation you're now a master of using the Suspense APi and lazy loading component, don't hesitate to try it out. It seems slightly more complex but with more practice, you will get the hang of it. 

Don't forget to leave a comment or chat with me on [Twitter](https://twitter.com/Derickzihalirw5).

See you 👋