Consuming a REST API with React Hooks (using design patterns)

Taking the basics, a bit further

Micaiah Wallace
Nov 26, 2020 · 5 min read
Image for post
Image for post
Photo by Maximalfocus on Unsplash

Introduction

This concept is a key one to grasp and use when developing react web applications. For the sake of this article we will simply focus on how it pertains to requesting data from an API and using it within the application. We will be looking at:

  • The basic setup for consuming APIs with react hooks
  • Abstracting low level plumbing calls away
  • Further abstracting where it makes sense

Basic API Request Flow

Image for post
Image for post
Photo by Samuel Sianipar on Unsplash

There are quite a number of articles available to read which aid in learning how to setup the basic plumbing to make a react app communicate with a REST api, usually something like so…

Not bad, this will get your feet wet in the overall flow of requesting asynchronous data in the react ecosystem, however lacks quite a bit in practicality and here’s why.

  1. The component above is very tightly coupled to how the data is retrieved, rather than just the data.
  2. It also doesn’t provide response error handling.

Separation of Concerns

Image for post
Image for post
Photo by Alex Radelich on Unsplash

A first step to improve this code would be to extract the bulk of the logic into a separate custom hook so that the consumer isn’t responsible for knowing how or where the data comes from, hence creating more separation of concern.

This provides us looser coupling in the TodoList, allowing the logic that retrieves the todos to be handled by a more focused, single purpose component.

Abstract Low Level APIs

Image for post
Image for post
Photo by Clint Adair on Unsplash

The TodoList is starting to look better, but we still have a few problems with the way the request logic is working in our custom hook. It still requires knowing the plumbing of how to access the data, which should be moved to a lower level considering we are still operating in the business logic realm. Let’s start by abstracting the fetch call into another hook, and while we’re at it let’s add some error handling.

Let’s also create another file to store our request options for different requests, so that we don’t need to dig through a ton of files to change out request URLs.

Then we modify the useTodos hook to implement the new request abstraction hook like so. Notice we add a useMemo call so that the request object becomes cached upon creation, thus returning the same reference to the request on every subsequent render. This serves the purpose of preventing extra unnecessary API calls from the useApiResult custom hook. The reason this works is because the useEffect hook will check the request variable for changes on every render. Since request is an object it will check for changes by reference rather than value.

use the useMemo() hook to cache objects and prevent extraneous API calls

Now we can add the changes to display any request errors in the TodoList that come from the hook.

Finally we are starting to see a flow that allows room for change in the underlying plumbing while allowing the presentation and business logic to remain less affected. However, there is still another step that could be taken to abstract the plumbing just a bit further.

Abstract even Further!

Image for post
Image for post
Photo by Talia Cohen on Unsplash

Let’s take the fetch call and wrap it with a unified request interface so that if we decide to use another request library, it will be easier to swap out later. We will then provide this function via a react context and a custom hook that wraps the useContext function. This will make it accessible to any component or hook wrapped within the context provider component. We will also add the context provider component to our app near the top of the component tree to ensure the components have access to the request context.

In short, here’s what we are going to do:

  1. Create a new context and wrap the App with it’s provider
  2. Abstract context usage with a custom useRequest hook
  3. Create a request lib with a unified interface, pass into context’s value
  4. Use the hook wherever fetch call’s were being made

To Conclude…

I hope this information was useful and you’ve learned how to properly perform API requests within a react application, or at least ideas on how to improve your code base using abstraction and separation of concern.

Image for post
Image for post
Photo by Mark Basarab on Unsplash

Weekly Webtips

Explore the world of web technologies through a series of tutorials

Sign up for 💌 Weekly Newsletter

By Weekly Webtips

Get the latest news on the world of web technologies with a series of tutorial Take a look

By signing up, you will create a Medium account if you don’t already have one. Review our Privacy Policy for more information about our privacy practices.

Check your inbox
Medium sent you an email at to complete your subscription.

Micaiah Wallace

Written by

software engineer. minimalist. enjoy creative software solutions.

Weekly Webtips

Explore the world of web technologies through a series of tutorials

Micaiah Wallace

Written by

software engineer. minimalist. enjoy creative software solutions.

Weekly Webtips

Explore the world of web technologies through a series of tutorials

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store