Moving your HTTP layer into a reusable React component

The_Polyglot
4 min readMay 2, 2022

The Idea

When building a react app, most pull their HTTP related behavior out into a separate service. That service might be a bunch of separately exported functions that use currying to bootstrap some common behavior or a class that handles some up front configuration in it’s constructor. That HTTP service would either then be used in the component that needs the data or its parent component that handles fetching and feeding data into it’s children (referred to as the container component pattern) would make the request.

Example of using an HTTP service within our component

We can get fancy and add a facade over top of this that defines the url within the service that changes based on the method called such as shown below.

This would result in a lot of code duplication but we could argue would be leave our view layer less concerned with that layers details.

Remove all these hooks and logic

But what if we could remove the repetitious hooks (useEffect, useState) and state management every time we needed to simply fetch some data and provide it to a component ? This could clean up our components drastically. This is where the Data Fetch component comes in to the picture

How it works

Let’s say we have a UserListing component that needs an array of objects containing user data in order to work. It’s a very common use case across any application to fetch several of an entity and do something with it. Instead of fetching it within our parent component which is App.js we will provide our UserListing component and a url as props to a new component were naming FetchAndFeed.js. Our App component doesn’t need to understand anything that happens after this. The FetchAndFeed component will handle fetching the data needed for the url provided and will render the child component with the data fetched as its prop. The diagram below provides a visual representation of this.

What it looks like

Let’s start with our App.js component which would typically maintain any business logic needed to be abstracted from the child view components.

If we were using an HTTP service to make our requests, we would need to

  • import useState & useEffect
  • define the state variable and setter for our data that is returned
  • make a separate async method that is called from our useEffect method (this is a react best practice for asynchronous behavior).
  • Call the state setter with the newly returned data as well as feed it into the UserListing component.

Thats a lot (15+ lines) removed already and this functionality is likely duplicated across several different listings in our app.

Fetch and Feed Component

Here is a breakdown of what the FetchAndFeed component is doing:

line 4: we’re now generalizing state to exist once within this component rather then across endless container components. We will assume that fetched data will exist as an array.

line 6–14: all of the userEffects that are used across the app for data retrieval can now be moved to this one component. In a larger application, this will be where you will define more http related options or perhaps pull in a npm package such as axios rather than the native fetch().The data is fetched and set within local state.

line 16: this part is important. The only way to use a component provided as a prop is to use React’s cloneElement method. The first argument is the provided child and the second is the props we want to provide it. In our case will provide an object with the data property holding our user listing.

Then the child component will receive the fetched listing and can do as it pleases with it.

Pros

Removes duplication

React components are essentially functions and we’re having our FetchAndFeed function/component do what functions do best, remove code duplication.

Easier to understand

As a developer it takes time to look at the useEffect, state management and HTTP layer it’s calling every time I begin working with a parent component. After reviewing how the FetchAndFeed component works, it’s completely transparent what is happening every time we see it being used. This can change as we add more props and external configuration to the component but we have the ability to keep things simple for anyone referencing it.

Configure once

If our base url changes, we can change it within our once configured component. The same is typically accomplished with a service layer but its worth pointing out that the same is easily accomplished from this approach

Cons

Mixes our infrastructure layer with a view templating

For those who have read the clean architecture book and insist on its teachings, this might be seen as bonding our infrastructure layer too tightly to react which is a view layer library. Theres something to be said for having all of your app’s external communication logic in one place. What I did as a compromise was store my fetch and feed components within a sub directory of my http directory layer. You can also pull your url’s out into an object within your HTTP designated directory. Your view layer will again have no hard coded urls.

--

--

The_Polyglot

Live to share and teach. The numbers mean nothing if I reach 1. 8 years startups, now at 🍏