Check out a free preview of the full Complete Intro to React, v9 course
The "use & Suspense" Lesson is part of the full, Complete Intro to React, v9 course featured in this preview video. Here's what you'd learn in this lesson:
Brian uses the Suspense component to provide fallback content while its children are loading. Once the loading is complete, the fallback content is swapped out for the rendered child component. The "use" hook is also introduced. Unlike other React Hooks, "use" can be called within loops and conditional statements like if.
Transcript from the "use & Suspense" Lesson
[00:00:00]
>> Brian Holt: Let's talk now about use and Suspense. We've been talking on and off for years at this point about Suspense. They announced it forever ago, and then they got really close to releasing and they're like, no, we don't wanna release it. And then they're kind of coming back and ready to release it again.
[00:00:18]
And kind of what they're recommending is we don't really want you to use Suspense directly. We want you to use things that use Suspense for you. So cuz it's kind of a strange API, but they're getting closer and React 19, it'll finally be stable, and I'm gonna show you how to use it.
[00:00:38]
Yeah, I'm gonna show you how to use it today. So one of the cool things is it's actually usable by TanStack Query. They'll use it for you which is pretty cool. So we're gonna do that. So I want you to head over to app.jsx, and we're gonna give this some configuration to QueryClient here, and we're gonna say defaultOptions
>> Brian Holt: Queries, and we're gonna say experimental_prefetchInRender, and we're gonna set that to be true.
[00:01:17]
>> Brian Holt: All right, let's go back to past.jsx, sorry, past.lazy.jsx, and we're gonna import a couple of things up here from React. We're gonna import a useState, which we have already. So I don't need to do that, but we're gonna import Suspense with the capital S and use, just use.
[00:01:51]
>> Brian Holt: So, we wanna show a really nice loading page that's not like this one when we're loading pass orders. So here inside of this error-wrapped post-order, we're gonna abuse this higher-level component a little bit and put some more stuff in here. So one, we're gonna move page just up into this component.
[00:02:16]
And we're gonna move our use query here as well up into that, right?
>> Brian Holt: Now, the interesting thing that we're gonna do here is I'm gonna just call this loadedPromise. And then just here before the semicolon, I'm gonna put .Promise. This is gonna give you access directly to the promise of this use query that's generating.
[00:02:59]
So inside of the error boundary, I'm gonna put one called Suspense. And I'm gonna give it a fallback of something nice that like hey, I'm loading. So I'm gonna say div className = past_orders and h2 of Loading Past Orders.
>> Brian Holt: And then outside of that, I'm gonna say close Suspense.
[00:03:37]
This also needs to be closed.
>> Brian Holt: Okay, now that I'm tracking page and the promise outside of this, I have to pass this into past orders here. So I'm gonna say loadedPromise = loadedPromise.
>> Brian Holt: And page = page.
>> Brian Holt: Bear with me, we're getting there. All right, so now we have this promise being passed in, you have to pass in setPage as well.
[00:04:19]
I do you have to pass in setPage, so page and setPage, sorry.
>> Brian Holt: So we're passing in loadedPromise page, setPage. You can ignore these props because there's not actually any props that we care about, but they were there from me previously putting them there. So if you want to, you can leave them there, okay.
[00:04:45]
This loadedPromise represents the data that's going to be there eventually, right? So it's a promise of the data that's coming.
>> Brian Holt: So what I need you to do is, I need you to say const data = use this has to be coming from props. So we have to destructure this.
[00:05:16]
So I'm gonna put page, setPage and loadedPromise, and data = use loadedPromise. There's too many parentheses here.
>> Brian Holt: There we go. So this is the line that I'm concerned that you might be looking at, like, what the hell is that? So follow with me for a second. Suspense is basically saying here is a boundary that stuff inside of it might be loading.
[00:05:54]
When it's loading, render the fallback. When it's not loading, render whatever is inside of it. What we're doing here is we are passing in a promise of the data. So the reason why we brought this outside of the Suspense boundary, it works like the error boundary. That this has to exist outside of the rendering thing because it can't render if it's not working, right?
[00:06:23]
I guess we have to pass in the isLoading. I guess you can just delete the isLoading thing cuz this will never hit. So you can delete that. We're passing in this promise, this loadedPromise, and what's happening is this is another react thing. It says all right if this promise is not loaded yet, suspend this component.
[00:06:44]
Don't render it, stop here and tell that Suspense component above me, I'm still loading, right? So it's going to hit this line. It's actually probably good if you can put this line first cuz you wanna run as little code as possible here. It's going to go Backup is like, hey, Suspense, I'm loading, and then it's gonna load this fallback for you.
[00:07:05]
Eventually, when this promise resolves, it's gonna be like cool, I'm good now, and then it's gonna let this continue rendering. Now, what's cool about that is what happens later when we set the page to be something different again. It's gonna send it back to Suspense, and then it's gonna go back and forth.
[00:07:27]
>> Brian Holt: Is this better than what we had? Maybe, I think so because now this component has no concept of loading. Once it unsuspends itself, the data is all loaded and this reads like it's all just linear loaded code. I think it's kind of nice if you can get past this.
[00:07:47]
This is kind of a weird API, but some people put one Suspense at the top level of their app and it's like this is a loading state for my entire app. It's not the most user friendly thing, but you could do it that way. And some people will do it like this, where it's more localized.
[00:08:06]
So I mean, let's make sure that I'm not telling you all lies. That could happen. This was past orders, so loading past orders.
>> Brian Holt: And it loaded, same thing if I hit Next, it's gonna go back to this Loading Passed Orders thing, and then it's done. And then because it's TanStack Query, it's all cached well so you don't hit that loading state again.
[00:08:36]
>> Brian Holt: I think this is quite nice.
>> Brian Holt: Another kind of fun fact, can I do this really quick here? I don't have it in here, but let's go look at Header.jsx really quick. They made use do several things, it's become this, there it is, where we have used context here.
[00:09:05]
You can also just use it with use now,
>> Brian Holt: And do this.
>> Brian Holt: Surprise, you might say, who cares? And fair thing to say, but you can now do that with React 19.
Learn Straight from the Experts Who Shape the Modern Web
- In-depth Courses
- Industry Leading Experts
- Learning Paths
- Live Interactive Workshops