Fetching API Data With React-Async
Tags: reactasync, api, javascript, react
Published: 2019-08-20 10:33:26

As developers,when making api requests, especially with react, we are always faced with the choice of either using the javascript fetch API or axios library. Picking one of the above has always worked great depending on the developers needs and usage. 
However, I was curious in finding out other ways of doing things, and that was when I discovered a package: react-async.

This post is my attempt to understand and to teach myself the usage of the package

##Introducing React-Async

React component and hook for declarative promise resolution and data fetching [ documentation ](https://www.npmjs.com/package/react-async)



One of the benefits of using the package is:

- It also works with promises, async/await and the Fetch API


The rest of this post will be code. Brace up😁😁

We will be using the react cli

First install the react cli: create-react-app ( CRA )
 
```javascript
npx install create-react-app async-react

cd async-react

npm start
```

Note here that i am using npx to install CRA and bootstrap my project.
This saves me the time of first installing CRA globally in my system and then bootstrapping the project

But for your needs
```javascript
npm install -g create-react-app
create-react-app async-react

cd async-react
npm start
```


Awesome!!! Our development environment has started


Open our project folder in your favorite code editor, and then move into the src folder


This is where we do most of our work

Rename App.js to Posts.js. We shall be rendering a list of posts

Open the Posts.js file and type in this code

```javascript
//import react and react-async

import './App.css'
import React from "react"
import Async from "react-async"

const loadPosts = () =>
 fetch('https://jsonplaceholder.typicode.com/posts')
    .then(res => (res.ok ? res : Promise.reject(res)))
    .then(res => res.json())

const Posts = () => (
  <Async promiseFn={loadPosts}>
    {({ data, error, isLoading }) => {
      if (isLoading) return <div>Fetching data... Please Wait</div>

      if (error) return <div>Something went wrong: ${error.message}</div>

      if (data){
          const responseData = data.map((post)=>{
            return(
              <div>
               <p> {post.title} </p>
               <hr />
               <h1> {post.body} </h1>
              </div>
            )
          })
        return(
          <div>
           {responseData}
          </div>
        )
       }
      return null
    }}
  </Async>
  
)

export default Posts
```

At the top we are importing react and react-async 

But we still don't have the react-async package yet
Lets install it

```npm install --save react-async```

There are three ways to use react-async

- As a hook
- As a component
- As a factory

We are using the **As a component** functionality

###Code Illustration

We create a loadPosts function which makes an api request using the fetch api
This request returns a promise which gets resolved or rejected.

If it gets resolved, it makes available some props to our component which includes -

- data : The api request was successful and we have our data to inject into our component

- error : Unsuccessful api request. This holds details of what went wrong

- isLoading: The data response from our api is yet to arrive, so we wait until it is resolved

In the Posts component, we make use of the props being made available to us and return the data

Take note of this line 

```javascript
   <Async promiseFn={loadPosts}>
```

This is where the magic happens

We pass in the loadPosts function which makes the api request as a prop to the Async component and when it gets resolved, we are provided with the data, error and isLoading props which we can then use in our Posts component

Recall we imported Async from react-async

###Update
Open index.js file and make the appropriate changes

```javascript
//remove 
import App from './App'

//Add
import Posts from './Posts'

ReactDOM.render(<Posts />, document.getElementById('root') )

```

With these out of the way, our app should be working