React Data Fetching
Tags: react, fetch
Published: 2020-03-22 23:06:02

---
title: React Data Fetching
published: true
description: I'm looking for a better way to handle data fetching and updating in React
tags: [react, fetch]
cover_image: https://dev-to-uploads.s3.amazonaws.com/i/ffw8fv9kik6ibk0qj8xz.jpg
---

# React Data Fetching

I'm looking for a better way to handle data fetching and updating in React, when I say better I mean something more than my current bare bones Axios implementation.

Things that are important to me:

* Size
* Typescript
* Active Community/Support

To the cloud! After searching [reddit `r/reactjs`](https://www.reddit.com/r/reactjs/) for `fetch` and picking through the posts I came up with a few libraries that seemed to fit the bill. In no particular order:

- [React Query - Hooks for fetching, caching and updating asynchronous data in React](https://github.com/tannerlinsley/react-query/)
- [Rest Hooks - Delightful Data Fetching](https://resthooks.io/)
- [SWR - React Hooks for Remote Data Fetching](https://swr.now.sh/)
- [React Async - Flexible promise-based React data loader ](https://docs.react-async.com/)

## Stats
First, let's look at the stats at the date of writing this post:

### Github

| Github      | Contributors | Issues | Last change | Stars |
|-------------|--------------|--------|-------------|-------|
| React Query | 36           | 1      | 15 hours    | 4k    |
| Rest Hooks  | 17           | 9      | 2 days      | 924   |
| SWR         | 42           | 52     | 5 days      | 7.3k  |
| React Async | 21           | 20     | 18 Hours    | 1.7k  |

### npm

| npm         | Version | Weekly | Published | Size   |
|-------------|---------|--------|-----------|--------|
| React Query | 1.0.7   | 10,583 | 16 hours  | 357kb  |
| Rest Hooks  | 4.5.2   | 2,871  | 3 days    | 725kb  |
| SWR         | 0.1.18  | 31,103 | 5 days    | 76.7kb |
| React Async | 10.0.0  | 15,637 | 3 months  | 337kb  |

SWR wins on stats it's the smallest and most popular of the bunch.

## Playtime

I'm going to try each of the libraries for a couple of hours and see how far I can get converting a page over from vanilla Axios calls to use the library. The page I'm trying has a nested data model of a Story with many Tasks and many Comments.

![Story Data Model](https://dev-to-uploads.s3.amazonaws.com/i/05a5ucscb41zv4q85rfr.png)

### React Query

#### [Installation](https://github.com/tannerlinsley/react-query#installation)

Simple install then straight into sample code, looks simple enough will try fetching my top level, Story model.

#### [Usage](https://github.com/tannerlinsley/react-query/tree/master/examples)

- [Query keys are important](https://github.com/tannerlinsley/react-query#query-keys)

**PROBLEM** - Typescript typings don't seem to work out of the box ☹️

Seems the @types/react-search typings are out of sync with the current version too. Ho hum, I've stuck a global module typing in for now.

```
declare module 'react-query';
```

The fetch status returned from `useQuery` match exactly the ones I'm using in my vanilla Axios fetcher, handy!

The first call to the backend failed but error handling picked it up nicely, its
also retrying a few times at different intervals 😀 [Retry Docs](https://github.com/tannerlinsley/react-query/tree/92bdf704d3ab776d26b7759e0e95fefa9796e0f7#retries)

The page is also auto refreshing when I move away and back to the browser, another plus for react-query 😀

Fixed the query problem and top level Story being returned and cached 😀

Onto the child data...

Works exactly the same as the parent component just run the `useQuery` hook in the child components.

#### [Mutations](https://github.com/tannerlinsley/react-query/tree/92bdf704d3ab776d26b7759e0e95fefa9796e0f7#mutations)

As well as queries the library also allows mutations, will try sending some updates...

Updates work but I couldn't get the cache manual update to work. I was hoping to push an updated task into the cache an have it render immediately. Then call a server refresh but I couldn't get that to work. Maybe with a little more time but my few hours are up. It does look like this is worth coming back to revisit.

My couple of hours are up, how was it?

- Very easy to get going, I was querying data with very few changes to my current code base
- Auto refresh was an unexpected surprise
- Query and caching worked well but mutation took more work which is to be expected

### Rest Hooks

#### [Installation](https://resthooks.io/docs/getting-started/installation)

- Babel config
- Add Cache Provider
- Add Suspense and ErrorBoundary

#### [Usage](https://resthooks.io/docs/getting-started/usage)

- Define a resource

Looks promising my project is using Typescript and already uses typed data models so this should be a good fit.

**PROBLEM** - Resources need a defined url, the url I use for the Story model is not static 🙃
How do we handle that? My url would have to be `/backlog/{id}/stories`.

Looks like we can handle this: [https://resthooks.io/docs/guides/url](https://resthooks.io/docs/guides/url)

- Loading state and error states are handled at a high level on the component tree, or it looks like you can have lower level handlers if you like.

- Cool we have top level data returned, now can we get the child data...

- No problem with child data we just define Resource models for Tasks and Comments and they work

My couple of hours are up, how was it? Good mostly 'it just worked'.

- Good docs
- Suspense support was nice
- High level Error handling
- Felt opinionated which is not a bad thing as long as you agree with the opinions 😀

### SWR

> The name “SWR” is derived from stale-while-revalidate, a cache invalidation
> strategy popularized by HTTP RFC 5861. SWR first returns the data from cache
> (stale), then sends the fetch request (revalidate), and finally comes with the
> up-to-date data again.

#### [Installation](https://github.com/zeit/swr#usage)

Quick start guide seems simple enough, let's give it a try.

- Loading of top level data working first time, either this is an easy to use library or I'm getting better using the libraries 😉

- On to the child data... Looks like SWR has us covered here using [Dependent Fetching](https://github.com/zeit/swr#dependent-fetching)

  > SWR also allows you to fetch data that depends on other data. It ensures the
  > maximum possible parallelism (avoiding waterfalls), as well as serial
  > fetching when a piece of dynamic data is required for the next data fetch to
  > happen.

- Child data working first time too, so far so good. On to mutation!

#### Mutations

Got it working after wrestling with React Array item mutations, think I now know how to get the mutations working in react-query 😀

- [Suspense support](https://swr.now.sh/#suspense) too 😀

How did it go? Really well, there is a lot to like about SWR. No wonder it's so popular!

- Small
- Typescript working out of the box
- Refresh on re-focus
- Suspense support
- Popular

## React Async

### Installation & usage

Installation was straight forward, there are 3 different ways to use the library:

> React Async offers three primary APIs: the useAsync hook, the <Async>
> component and the createInstance factory function. Each has its unique
> benefits and downsides.

I'll be trying the `useAsync` hook as it most closely matches the other libraries but the `Async` components look interesting.

Let's try and load the top level data.

**PROBLEM** Typescript setup was a bit funky, good description on how to get it working here [React-Async with TypeScript](https://www.schannak.com/posts/2019-15-03---React-Async-Typescript/)

Once the TypeScript problem was sorted it was onto loading the child data which was straight forward 😀

Now does it handle mutations? React Async has us covered with [optimistic updates](https://docs.react-async.com/guide/optimistic-updates)

How did it go? The typescript problems at the start slowed me down for a while but it was all go after that.

- Cuts out a lot of the component boilerplate
- The helper components look great
- Suspense support
- No caching 🙃

## Conclusion

[SWR](https://swr.now.sh/) wins for me, it easily meets my criteria of:

* Size
* Typescript
* Active Community

I though its popularity might have been due to its [next.js](https://nextjs.org/) roots but it really stands out on its own. Definitely worth further investigation!

Maybe you have some other favourite?