Asynchronous State Management With React-Query | by David Van Fleet | Apr, 2022

Wrapping our requests in useQuery and utilizing the cache key implies that we don’t really want to consider state administration in any respect for the information we obtain from community requests

Take a second to consider the shared state in your newest React undertaking. For many apps, this may increasingly embrace the at the moment logged-in consumer.

A weblog utility could embrace all obtainable weblog posts or all of the weblog posts written by a particular writer.

A health app could embrace a listing of workout routines for a specific muscle group.

A baseball app could embrace the batting statistics for a particular participant. Actually, the shared state in our React apps may be absolutely anything!

However what do all of those items of state usually have in widespread? We entry them by way of community requests (both to our personal backend or to a third-party API).

Let’s check out how we are able to use customized hooks and react-query to handle these items of state that come from asynchronous community requests.

In our instance, we’ll be closely utilizing the useQuery() hook from react-query. This hook takes three arguments —

  1. a cache key for the request we’ll make
  2. a question perform
  3. an choices object.

For all our examples, let’s think about a health app that enables customers to seek for workout routines by muscle group. First, let’s get a radical understanding of how we are able to use useQuery() to make a community request that will get all again workout routines from our imaginary API.

First, we’ve outlined our question perform, fetchBackExercises(), which makes a request to our imaginary endpoint, /workout routines?muscleGroup=again.

We will think about that this endpoint will return a listing of train objects as JSON that can be utilized in our react utility to to create a element that lists the workout routines.

Truthfully, this appears to be like somewhat messy to me. I like my parts to be as readable as potential, and there’s a complete lot of JavaScript in there that makes it too powerful to know what’s occurring with a single look. Let’s refactor a bit to place all the question logic right into a customized hook.

That is wanting higher! The entire logic across the community request for fetching workout routines is now encapsulated in our customized useExercises() hook.

The hook takes one argument, muscleGroup, so it may be reused wherever in our app simply.

The muscleGroup arg is used each within the question param within the precise community request, and can also be used within the cache key of the useQuery hook, which is able to change into necessary shortly.

This permits us to simplify our <ExerciseList /> element so that each one we’re doing is looking our hook, and mapping the end result to create our record of parts.

Up to now we’ve acquired a fairly clear, reusable hook and element, however what does this should do with state administration? The reply lies in react-query’s caching.

Keep in mind that the primary argument of the useQuery() hook is a cache key. The response of each community request made by way of useQuery() is saved in a cache utilizing that key.

Earlier than making a request, react-query will test the cache. If the identical key already exists within the cache, useQuery() will merely seize that cached response and return it, as an alternative of losing assets on making the identical request once more.

Basically, because of this react-query’s cache turns into our knowledge retailer for any state coming from community requests (which for many apps is just about every thing!).

In our instance of a useExercise() hook, many differnent parts could use the hook to request workout routines for muscleGroup: 'again'. The precise community request will solely be made as soon as, and each subsequent name of useExercises('again') will merely seize the response out of the react-query cache.

The identical is true for some other muscle group we request ( useExercises('chest'), useExercises('biceps'), useExercises('legs'), and so on). Since we go the muscleGroup argument into the cache key ( ['exercises', muscleGroup] ), every new muscleGroup will set off an precise community request, however every subsequent request will use the cache as if it’s simply some other piece of state.

So what are the advantages of managing our async state this fashion? Wrapping our requests in useQuery and utilizing the cache key implies that we don’t really want to consider state administration in any respect for the information we obtain from community requests.

We don’t want to fret about context/suppliers, and we undoubtedly don’t want to fret about any third-party state administration libraries. Managing async state this fashion permits us to maintain clear, maintainable, easy, readable code.

More Posts