Today we are going to create a simple hook that helps me everyday in my React projects, both web and react-native: a hook to make Ajax Calls and that returns the response.

For testing the hook, we are going to build a simple app that will display all the Houses of Game Of Thrones, provided by https://www.anapioficeandfire.com.

To summarise, this is what we are going to do in this article:

create a new React Hook

this Hook will accept an URL to fetch and a series of options (queries, method and body)

this Hook will return an object with the AJAX response and a loading and error boolean values

Every time one of the options given to the hook is changed, the Hook will fetch again the URL

create a demo app to test this useFetch Hook

First, let’s create the skeleton app ☠️

I think I made this step 300 times in the past years, but I always find myself googling the correct command to use with create-react-app. I think I have some sort of selective forgetfulness for this simple command… so this part is more for the future me than for you :)

And after installing all the right modules, we go to https://localhost:3000 and the app is running :)

Create the hook

Let’s start by creating a folder in src called hooks and create inside a file called useFetch.js .

And inside the file we will put this:

Let’s take a look together at the code of our hook. There are two utility function that I’m not going to explain here, but if you need any help you can always contact me and ask :)

We are going to explore the hook part by part:

The hook will accept 2 parameters:

an URL

a ‘options’ object, that inside will have

a HTTP method (GET, POST)

a body, if you are going to use the method POST

a query, where you are going to put all the query params of the AJAX call.

Important: I specified only GET and POST methods. This is because this hook is made only to fetch data, not to update/create resources. Normally you should always use GET requests to fetch data, but since some APIs in the wide Internet are also using POST requests I decided to add that as well.

We are going to use the hook useState to store some internal variables, that at the end of the hook will be returned to the React component. We are going to initialize the state with an object with 3 parameters:

Response, that will contain the JSON response of the API called

Error, in case the response status is not ok

Loading, that will be true if the hook is still fetching the request. Since we are going to call the request as the next step, loading is already set to true

Inside useEffect

Let’s continue to explore the hook. Here we are going to use the hook useEffect to do something only when something in the params changes; if the component changes the url or any of the params inside options (query, body, method), the useEffect function will re-run.

We are using JSON.stringify to return a string of our options values. In this way the useEffect won’t have any problem noticing changes even if the object is nested.

The first thing that we are going to do is to change the value of the data state with:

loading set at true

error set at false

response will still be the previous response (null for the first time). This will help if you want to display the old data even when you are fetching the new data.

Fetch for the rescue 🚀

We are going to use the fetch function to make the AJAX call. We are going to add the header Content-Type to application/json since we are going to use only APIs that requests json parameters.

Just a note: instead of throwing an error if the response is not ok (like axios), fetch is still resolving successful, but will have a response.ok set to false. For this reason we will need to check in the resolved data if response.ok is true or false and set the error state field accordily.

Every time the fetch method resolve or throws an error, we are going to update the data state with all the right fields, setting loading to false.

And… that’s it ✨

This is everything about the hook, now we just need to use it 🚀

Let’s build our demo app!

We will use the “An API of Ice and Fire” https://www.anapioficeandfire.com/ to create a simple paginated app that shows all the different Houses in the “A Song of Ice and Fire” series.

NB: all the code can be found on my Github page. As you can see, I removed some unused files from the boilerplate create-react-app. Also note that this is the final result, at the end of this article.

Let’s go to src/App.js and replace the content with this:

And this will be the result.

We haven’t add any style yet, so it’s pretty ugly. We can fix that by adding some CSS in src/App.css (we won't use any fancy styled-components or scss module or any of the things that the cool kids are using these days since it's only a demo).

That’s much better!

Support pagination (and queries to useFetch)

So right now we are showing only 10 houses. That’s ok, but I think that we can do better. We are gonna change the code to add some buttons to go to the next (or previous) page and view new results ✨

But first, add some style

Let’s add some extra style that we will need in the next steps: open src/App.css and replace the content with this:

Use useState to handle the currentPage variable

We are going to use a currentPage variable to be aware of what is the current page shown in the app, so let's setup that in our src/App.js

We initialise the value of currentPage to 1 and we also edited the page value of the useFetch query object to use currentPage instead of the constant 1 of before.

Now, let’s add some extra parts in the JSX. We are going to:

add a title, with the current page number inside;

add under the list of Houses the pagination section, with the 2 buttons to change page;

move the Loading div, so the title and the pagination section will always be visible.

And… we are ready! Let’s try it on localhost:3000

Let review what we have done today:

created a new React Hook ✔️

this Hook will accept an URL to fetch and a series of options (queries, method and body)

this Hook will return an object with the AJAX response and a loading and error boolean values ✔️

Every time one of the options given to the hook is changed, the Hook will fetch again the URL ✔️

create a demo app to test this useFetch Hook ✔️

We can still do better.

In the next weeks I will release a new tutorial that will enhance useFetch to:

automatically transform the response

conditionally call the AJAX call (now it’s calling it immediately)

add a default response (useful if you don’t want to call the API immediately)

add support for redux and dispatch

As always, message or follow me on Twitter if you have any questions 💛