Check out a free preview of the full Complete Intro to React, v8 course
The "React Query" Lesson is part of the full, Complete Intro to React, v8 course featured in this preview video. Here's what you'd learn in this lesson:
Brian demonstrates handling asynchronous state management, including fetching, caching, synchronizing, and updating server state by using the data-fetching library React Query.
Transcript from the "React Query" Lesson
[00:00:00]
>> We're gonna talk about React Query which is new to version eight of this course. I kind of held off on doing it for a while, I had been using it myself and my personal projects but it felt kind of optional, not totally best case and I think the react community has moved far enough along that react query is not really optional anymore.
[00:00:24]
Basically everybody uses it all the time. So you know that all that increment, the rigmarole that we did in the use breed this to capture this use cash and all this kind of stuff, where it makes request to an API and then it caches it and if it's in the cache and it serves that if it's not react courageous does all this stuff for you.
[00:00:45]
It is just like, here's the key, here's the URL, here's a refetch method, that's it. And then react query just handles everything for you. So, that's what we're gonna use today. The cool thing about React Query is it's now just, it's not just react now it works in angular, it works in svelte.
[00:01:03]
I think they're making it in solid, they're doing a bunch of stuff now. So it now exists outside of just react, which is pretty cool. And here is the secret for writing long term maintainable React code. The hardest part about React is useEffect. The most bugs you're gonna see the most confusing thing about wrapping your head about when does this effect happen?
[00:01:34]
Does this cascade into other effects which then cascade into other effects? It's the most cognitively burdensome part of React useEffect, right? Like describing to a person is like the full lifecycle of how breed gets populated is several sentences with probably several caveats, right? The nice thing about React Query is it you're gonna start removing effects from your database cuz it's basically going to handle all your API requests for you.
[00:02:12]
So, here's my very loose rule that I would like to throw out to you. Minimize effects in your code. If there's a library that can handle it for you, do that. Where you have effects, try and contain them to small testable areas. This is the secret to a long happy life with React.
[00:02:35]
Okay, so I'm gonna show you how to do that with your API request, which is 95% the use case for effects anyway. So, I want you to npm i @tanstack/react-query@4.10.1. If you do npm instal just react-query, you'll get version three, they've released version four. They now do it on this tanstack.
[00:03:11]
Name space, okay? Start my server again. Okay, the first thing that we're gonna have to do is an app.jsx. We have to instantiate the query provider. So up here please go and say import (QueryClient, QueryClientProvider) from 'attanstack/react-query. Here we're going to create our client, const queryClient. There is a thought process we could have multiple query clients throughout your app, that maybe different parts of your app need to make requests to the same place and you don't want them to share a cache.
[00:04:05]
I have no idea when I would ever want that, but it is possible. It's one of those times that I just feel like less flexibility is helpful here. But no one asked me. All right, so you're gonna say queryClient=new QueryClient. We have to give it a Config, defaultOptions, queries, and so basically it's gonna ask us like hey, how long do you want me to cache things for our pet API, and for our breeds lists, and everything like that?
[00:04:48]
I'm not anticipating the new pets coming up for adoption every second. That is probably fine for as long as the user is on a session. So the way that you say that is you say that the cash time is infinity. Again, staleTime and cashTime is infinity. Now, if you wanted to like cache for like 10 minutes, you could put that here.
[00:05:11]
I can't remember it's in milliseconds, right? So if I wanted 10 minutes I would do 1000 *60, *10, right? This would cash it for 10 minutes, but I don't want that. I'm telling you, it's like once you fetch something, don't refetch it. It's what I'm saying here. Same thing with cashTime, staleTime, both the same thing there.
[00:05:40]
All right, so inside (BrowserRouter), please put this component <QueryClientProvider. This works the same way as our BrowserRouter that it provides context whenever we're going to do the use query later. And the client= queryClient, like that. Okay, and then move your whole app inside of that. People will call things like (BrowserRouter) and (QueryClientProvider), higher header components that they're basically like wrapping components that they themselves don't display anything, right?
[00:06:22]
Just because I put this (QueryClientProvider) around my application it's not displaying anything, right? All it's doing is providing context to components underneath it, that's the whole idea here. It's kind of an awkward API, but it's also like maybe there's a part of my app that I don't want that context available to, you can only wrap certain parts of it.
[00:06:44]
There's ideas like that. Okay, so now we have a QueryClient available to us. Let's go write a method for fetching pets. This is what it's going to call on details.JSX, so that we can go and get the individual pet that we're looking at. So please create a file called FetchPet.js again, you can call it jsx this is gonna to be no JSX and here is just gonna be a method of fetching const Fetchpet=an async (QueryKey).
[00:07:19]
And then const id =queryKey(1). We'll see where that comes from in just a second, but just believe me for a second that this is an array and the second the one element is going to be the id. Const apiRes = await fetch (http://petsv2.dev-apis.com/pets?=(id). That's gonna go fetch your pet for us.
[00:08:02]
Then this is a thing peculiar to React Query. If it's an unsuccessful request, they want you to throw an error. Fetch will not always throw an error if you get like 500. If it's a 500, we wanna throw an error. So you're gonna say, hey, if apiaraes.okay then throw new error, and just give yourself a useful error message.
[00:08:36]
So the one that I put here as (details/s(id) fetch not ok). This is purely for debugging purposes, so just give yourself a useful error there. This is useful because then React Query's gonna catch this and it's gonna know like this doesn't work and. You can now do like an on error and a bunch of stuff like that.
[00:09:04]
This is something if you're gonna use React query, just get used to, you'll put this in basically every time. Okay, and then React Query expects you to return a promise, right? If you remember async functions always return promises, so we're good so far. So we don't have to await the Res.json, we can just return the apiRes.json.
[00:09:30]
Because what is this return? This return is a, it's a promise, right? You can see right there, it's a promise. What happens if I didn't return await? It'll work just fine but technically we don't have to await here so you'd actually miss a tick if the word tick doesn't mean anything, it's a no term don't worry about it [LAUGH].
[00:09:52]
But you'd basically unnecessarily introduce like a millisecond of latency in there Just a common thing that I see when people are writing React query, okay, and then down here we're gonna say export default fetchPet. Looks like I have an error here. I do. That should be there. Yeah, there we go.
[00:10:21]
I had the backtick in the wrong place here this is now a fetch method that is ready to be used with React Query.
Learn Straight from the Experts Who Shape the Modern Web
- In-depth Courses
- Industry Leading Experts
- Learning Paths
- Live Interactive Workshops