Check out a free preview of the full Intermediate React, v5 course:
The "useDeferredValue" Lesson is part of the full, Intermediate React, v5 course featured in this preview video. Here's what you'd learn in this lesson:

Brian demonstrates the useDeferredValue hook and explains how it can reduce re-rendering by caching data, like the results of a fetch request. If the current render is the result of an urgent update, React will return the previous value and then render the new value after the urgent render has completed.

Get Unlimited Access Now

Transcript from the "useDeferredValue" Lesson

[00:00:00]
>> So we just did advanced React performance for code splitting and server side rendering. We are about to do low priority rendering. So these are gonna take advantage of the two new React hooks use deferred value and use transition. Make sure you start with a fresh copy of adopt me which is gonna be this 14 Dash context folder.

[00:00:26] And make sure you npm install your dependencies, make sure you restart your dev server, normal stuff. So, I was a little conflicted if I was gonna show this to you or if I wasn't going to show it to you. But it felt disingenuous to show you some of the other more advanced React performance features and not show you this.

[00:00:49] So I'm gonna show you this on the pet adoption app and it's gonna feel like it's gonna do nothing because it's essentially going to do nothing for us. I'm gonna show you how it works. I'm gonna explain to you how it works. But it's gonna be solving a performance problem that our app doesn't have.

[00:01:07] So I just want to be super clear about that, nothing's gonna feel different after we're done doing either one of these performance fixes. So this is just to super underscore a point for all of you that React is designed and made to solve Facebook's problems, which means a lot of these advanced features are for Facebook's problems.

[00:01:29] So let me explain to you what use deferred value is going to do and when it might be useful and why we don't have that problem right now. So Facebook is designed around having islands in all of its various different pieces of its UIs, right? It has a news feed, it has ads, it has a posting box, it has a bunch of various different things.

[00:01:51] Every microcosm of that newsfeed has an entire team dedicated to it with multiple PMs, multiple designers, multiple engineers. And they're all working in concert with each other. Some of those things are really important that they have to update immediately. If a user clicks on something, you need to do that thing immediately or else the user perceives jank, they perceive that it's slow.

[00:02:16] It feels slow to them, even if it's probably not, right? That's problematic, users don't like that, users bounce when they feel like something's slow or not working. So enter use deferred value, specifically what use deferred value and use transition for is low priority re-rendering. So if a user clicks on something, they don't care if you're loading more stuff below the fold, right?

[00:02:41] They're never gonna perceive it. What Facebook wants to do is they want to drop re-rendering things that are below the fold or out of the way. And then wanna focus on re-rendering things that the user has clicked on, the things that the user is focusing on. So there's this notion of high priority rendering and low priority rendering.

[00:03:03] Now if you're thinking about your app that you're working on right now Some of you might be able to conceive of like, okay, this is a high priority thing, this is a low priority thing. I imagine most of us, myself included, it's all relatively the same, right? For the most part, I don't have so much stuff loading and so much jank in my app and so much danger of jank being introduced that I need to have this tiered notion of rendering.

[00:03:31] But I'm gonna show you how to do it because some of you definitely will run into them, and this is really cool. This is why they made these features is for this idea of low and high priority rendering. So everything that I've shown you so far is high priority rendering.

[00:03:46] I'm gonna show you how to identify something as low priority re-rendering. So that basically Facebook can say, I can drop this on the floor if something important happens, okay. So, yeah this is just a bunch basically saying all the stuff that I just said. To Facebook, half a second of rendering is millions of dollars, right, most of us don't have that.

[00:04:12] Bless you, if you do, please send me a check, okay. For something like the Facebook feed, this actually is a huge issue cuz they have so much stuff going on in that page. So what I want you to do is, I want you to open your SearchParams.jsx. Okay, up here at the top we're going to import useContext, useState, useDeferredValue, useMemo.

[00:04:52] And that's it. So underneath the pets declaration which is here, I'm gonna say const deferredPets = useDeferredValue pets and const renderedPets = useMemo And give it this function of Results pets=(deferredPets). And then only re-render when we see brand new deferred pets. Okay, and then we're going to go take this renderedPets down here where we have Results and we're going to render this out as renderedPets, like that Okay, so now if we go look at our search prams page at Here, okay, as you can see here, it looks exactly the same, it feels exactly the same.

[00:06:17] Even if we put this on 3G or something like that, it would feel exactly the same. So let's figure out exactly what happened here. So we have deferredPets which is taking this value in from pets. Pets is what's coming back from our API. What I'm asserting here is, if I get new pets back from the API, it's okay to interrupt re-rendering results.

[00:06:41] Imagine I'm rendering 1,000 results of pets or something like that, right? That can take some time, that can be milliseconds, centiseconds, decaseconds, something like that, other way round. Yeah, it can be in the order of a second, maybe two, especially on a low powered device. So what you're doing is you're taking this and you're using this useDeferredValue, which is basically saying, okay, I'm only gonna give you the real value of pets once I'm positive I got nothing left in my render queue, right?

[00:07:14] And so if I hand it back this pets, it's gonna give me back deferredPets, which is what it was before. Or it can be what it is now, it's one of the two. As soon as I give it pets the first time, it's definitely gonna give me back what it used to be.

[00:07:27] And then I'm gonna use memo here and basically say, all right, give me a rendered result of this with deferredPets. And only update this if deferredPets changes. We've used used memo before, right? We used it previously in the class. What useMemo does basically says, only update this if this value here changes, right?

[00:07:49] So with deferredValue, we only get a new value for deferredValue once it's definitely cleared out its queue of things to render, right? So basically we end up with this renderedPets being the results, right? That only gets updated when we're definitely sure that React's render queue is empty or low or whatever, right?

[00:08:11] But when it's not reacting to a high priority re-render from user interaction. That makes sense? So only use this if you're seeing problems of you have something that's expensive to render, that could be delayed. And your users are perceiving jank because they're trying to do something else instead of perceiving whatever it is we rendering there.

[00:08:39] That is when you use useDeferredValue. Does that make sense? If that seems very specific, that's because it's very specific. [LAUGH] Most of us don't have this problem, most of us will never have this problem, but that's how you do it.