Make HTTP GET Requests With Axios
Tags: react, productivity, javascript, tutorial
Published: 2021-05-21 19:23:13

The most common way for frontend programs to communicate with servers is through the HTTP protocol. If you're used to vanilla JavaScript, then you're probably familiar with the `fetch()` API which allows you to fetch resources and make HTTP requests. In this example I'm going to walk you through on how to use axios in React to make an HTTP `GET` request. Further on I'll walk us through how to make `POST`, `DELETE`, and even `PUT` requests. For now, let's stick to `GET`. Let's GET-er-done! (ok I'll stop).

<figure>
![Get er done](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/96ynou2pf1kktbjf0p1n.jpg)
<figcaption>Couldn't help myself</figcaption>
</figure>

Let's first create a `db.json` file in the root directory of your project in order to use the [JSON Server](https://github.com/typicode/json-server). For this example, I'm using data for a phonebook app I worked on.

```javascript
{
  "people": [
    {
      "name": "Hannah Rickard",
      "number": "06-51-99-56-83",
      "id": 1
    },
    {
      "name": "Hyun Namkoong",
      "number": "10987654",
      "id": 2
    },
    {
      "name": "Courtney Martinez",
      "number": "3691215",
      "id": 3
    }
  ]
}
```

Next, install the JSON server by running:
```
npx json-server --port 3001 --watch db.json
```
Note that the `json-server` runs on port 3000 by default, but since projects created with `create-react-app`  reserve port 3000, we need to define an alternate port.

The idea will be to save future contacts to the server, which in this case means saving to the `json-server`. The React code fetches the contacts from the server and renders them to the screen. Once a new note is added to the app, the React code will persist it to memory.

Let's install axios:
```
npm install axios
```

<figure>
![package.json](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ek6arjgn6y09o9zshmku.png)
<figcaption>Axios will now be added to the other dependencies</figcaption>
</figure>

Let's tweak the _scripts_ part of the `package.json` file so we don't have to type as much bc we're lazy.

<figure>
![Scripts](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/oary5fl8v4ybyo39rws3.png)
<figcaption>Nice and short</figcaption>
</figure>
Now all you have to type to start the json-server is:
```
npm run server
```
Nice! We're now ready to use axios. Open up two terminal windows, one to keep the _json-server_ running, and the other for react-app.

The axios library can now be imported in just like any other library in React. With a good ol' `import` statement.
```javascript
import React, { useState, useEffect } from 'react;
import axios from 'axios';
```
For this example I'm gonna assume you know about [React State Hooks](https://reactjs.org/docs/hooks-intro.html), and if not, I'll make a mental note for another blog :smile: .

However, [effect hooks](https://reactjs.org/docs/hooks-effect.html) will be exceptionally useful in our case becauuuse as the doc states:

_The Effect Hook lets you perform side effects in function components. Data fetching, setting up a subscription, and manually changing the DOM in React components are all examples of side effects._

Let's now dive in to our app.

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

const App = () => {

  // our state hook
  const [people, setPeople] = useState([])
  
useEffect(() => {
  console.log('effect')
  axios
    .get('http://localhost:3001/people')
    .then(response => {
      console.log('promise fulfilled')
      setPeople(response.data)
    })
}, [])
 console.log('render', people.length, 'people')

//...
```

Our faithful `console.log` gives us some hints as to what is happening here by clarifying the progression of the execution. The console prints out the following:
```
render 0 people
effect
promise fulfilled
render 3 people
```
* The body of the function defining the component is executed **first** thus printing out _render 0 people_. Meaning data hasn't been fetched yet.
* Our `useEffect` function is executed immediately after rendering.
* In result, _effect_ is printed followed by `axios.get` fetching our data.
* _promise fulfilled_ is registered inside our event handler for the operation and printed.
* Lastly, the `setPeople` function changes our `state` thus triggering a re-render resulting in _render 3 people_ being printed to the console. Meaning we've successfully fetched our data!

Let's refactor our effect hook:
```javascript
const hook = () => {
    axios.get('http://localhost:3001/people')
    .then(response => {
      setPeople(response.data)
    })
  }
  useEffect(hook, [])
```

This way we can now see that `useEffect()` takes two parameters. Firstly, a function, or the effect itself. Once again, the [doc](https://reactjs.org/docs/hooks-reference.html#useeffect) is our friend:

_By default, effects run after every completed render, but you can choose to fire it only when certain values have changed._

According to this, the effect is always run after the component has been rendered. In our case, we only want to execute the effect with the first render.

The second parameter of `useEffect()` is used to [specify](https://reactjs.org/docs/hooks-reference.html#conditionally-firing-an-effect) how often the effect is run. If the second parameter is an empty array `[]`, the effect will only run with the first render.
<figure>
![Noice gif](https://media.tenor.com/images/b2c96783c3862ba02c5cf22db7e19728/tenor.gif)
<figcaption>You can fetch with axios now!</figcaption>
</figure>

Well done! We've successfully performed a GET request with axios. We'll talk about sending data to the server in another post.


## Resources
* [axios](https://github.com/axios/axios)
* [Fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch)
* [JSON Server](https://github.com/typicode/json-server)
* [React Hooks](https://reactjs.org/docs/hooks-intro.html)
* [Effect Hooks](https://reactjs.org/docs/hooks-effect.html)