DEV Community

loading...
Cover image for React Data Fetching

React Data Fetching

Justin Ramel
・5 min read

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 for fetch and picking through the posts I came up with a few libraries that seemed to fit the bill. In no particular order:

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

React Query

Installation

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

Usage

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

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

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

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

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

  • 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

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

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 πŸ˜€

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
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

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

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 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 roots but it really stands out on its own. Definitely worth further investigation!

Maybe you have some other favourite?

Discussion (6)

Collapse
constantinchirila profile image
Constantin Chirila

Hey Justin, I would like to point out that in terms of size comparison please do use services like bundle-phobia.
Why would you compare the repository sizes then say that SWR at least in the size comparison. Gzipped react-query has 6.2kb, while SWR has 6.1kb. Basically the same.
I can't comment on the rest, but this particular issue really irked me as you mentioned a few times the miraculous size of SWR :)

Collapse
justinramel profile image
Justin Ramel Author

Hey Constantin, bundle-phobia looks like a great site thanks. I was going purely off the sizes reported on npmjs.com, react-query is currently reporting as 702 kB.

I've been meaning to post a follow-up about react-query, I'm now using it instead of SWR. The react-query dev tools are awesome!

Collapse
constantinchirila profile image
Constantin Chirila

Understanble, but what's reported on npm is the package size, not the bundle size. :)

Collapse
tylerlwsmith profile image
Tyler Smith

I really liked this–I had only heard of React Query. I'm going to try SWR on a project right now, I'm a huge fan of the projects Vercel works on. Have you had any problems with SWR?

Collapse
justinramel profile image
Justin Ramel Author

Hey Tyler, I'm also a big Vercel fan (next.js!) and I've not found any problems with SWR but... I'm now using React Query and find its Dev Tools to be a real game changer, being able to easily dig into the data during development is so useful.

I'd say give SWR a try and see what you think, its a great tool :-)

Collapse
tylerlwsmith profile image
Tyler Smith

Thanks for the insights!