Stale While Revalidate

Here we'll learn how to prefetch data based on the route

Project Source Code

Get the project source code below, and follow along with the lesson material.

Download Project Source Code

To set up the project on your local machine, please follow the directions provided in the README.md file. If you run into any issues with running the project source code, then feel free to reach out to the author in the course's Discord channel.

This lesson preview is part of the React Data Fetching: Beyond the Basics course and can be unlocked immediately with a \newline Pro subscription or a single-time purchase. Already have access to this course? Log in here.

This video is available to students only
Unlock This Course

Get unlimited access to React Data Fetching: Beyond the Basics, plus 70+ \newline books, guides and courses with the \newline Pro subscription.

Thumbnail for the \newline course React Data Fetching: Beyond the Basics
  • [00:00 - 00:10] In this video, we're going to talk about implementing stale while we validate in our data fetching library. But first, let's talk a bit more about what stale while we validate is.

    [00:11 - 00:38] The term stale while we validate comes from the HTTP cache control header, which basically means that if you already have cached data and you want to revalidate or re-veg that data, you can return the cached data immediately while re-veging the newer data in the background. Then once the data is fetched, the previously cached data is considered stale before the new data is fetched.

    [00:39 - 00:53] We can apply this strategy to our data fetching library in order to improve the perceived performance. This is especially useful for an app that needs to display up-to-date data like a stock market app or a social media feed.

    [00:54 - 01:11] If the user revisits the page, instead of waiting for new data, we can show the old's data or stale data immediately. Although our Pokemon app doesn't require real-time data, we can still implement stale while we validate just to demonstrate how it works.

    [01:12 - 01:37] The plan is to implement a way to refetch the data when the component mounts, and if the data already exists inside the cache, then we'll show that data first so that 'll be the stale data, and then in the background, we're going to refetch some new data and then update the homepage component with that new data. Let's go ahead and implement this in code by first adding the option to our home component.

    [01:38 - 01:48] At the end of line 9, let's add comma and curly braces, and in here we're going to create a new option called "refetch fun mount". And we're going to assign this to a value of 3.

    [01:49 - 01:58] Now if we save this file, it's going to reformat it with prettier. Let's talk about the check that we need to make before we can do a refetch on mount.

    [01:59 - 02:14] First we'll need to check if the refetch on mount option is set to true. Then we'll need to make sure that the status of the data is not loading or idle , since we're only interested in refetching data that has already been fetched.

    [02:15 - 02:27] Then in order to stop an infinite refetch loop, we need to check if the data is stale. Which basically means that if the data is older than a certain time, then we'll call it stale.

    [02:28 - 02:33] If these three conditions are met, then we can go ahead and refetch the data. Cool.

    [02:34 - 02:47] I know this sounds really complicated, but as usual, it's going to make much more sense when we start implementing it. So with that out of the way, let's go ahead and write this code inside our data loader file.

    [02:48 - 03:01] In our use data hook, let's go all the way to line 15, and we're going to hit enter a few times. And here, on line 16, we're going to add an if statement, which will first check if we have the refetch on mount option turned on.

    [03:02 - 03:19] So we're going to write options, then add optional chaining, and then we're going to write refetch on mount. And before I forget, let's add options as a third argument inside our code, so we'll scroll all the way to line six, and then after FN, we'll add comment and paste options.

    [03:20 - 03:36] Now let's go back to line 16 and inside our if statement, we're going to add another condition to check if this data.status is equal to the string of success. Now this condition can be changed to add error, so we'll check for success or error.

    [03:37 - 03:56] We can do that in the future, but for now, we'll just test for success. Then inside the if statement, we're going to call the prefetch data function with an argument of key function and a third argument of curly braces, which will contain the value of refetching and we'll set that to true.

    [03:57 - 04:20] Again, line 17 could have the fetch or use preloaded data function, but for now , we're going to use prefetch data to keep things simple. The refetching option doesn't yet exist inside our prefetch data function, but the reason we've added it is to change the state of our data to refetching in case the user wants to show a refetch specific loader or something else.

    [04:21 - 04:33] Let's now go to our prefetch data function and implement refetching. Let's scroll down all the way to prefetch data, which is on line 30, and first after FN, we're going to add a third argument and options.

    [04:34 - 04:51] We can add a new const variable called is refetching, and then that's going to equals options, then we'll do optional training and write refetching. Let's scroll down a tiny bit and below that, we're going to hit enter a few times and an if statement to check if it is refetching is set to true.

    [04:52 - 04:56] And if it is set to true, we're going to do a few things. We're going to set the data.

    [04:57 - 05:03] So we're going to write data cache dot sets. And in here, we're going to first set the key.

    [05:04 - 05:14] Then we'll add some curly braces and in here, we'll set status to a string of refetching. And of course, we'll have the controller, be new controller.

    [05:15 - 05:27] And then we'll have the payload, which is the data that's returned. And because we're implementing stale while we validate, we want to return the stale data, which is the data that already exists in the cache.

    [05:28 - 05:36] So let's write data cache dot get. And here we're going to add parentheses of key and we'll add optional training of payload.

    [05:37 - 05:42] So if there's no payload, it will just return undefined. Then we're going to write else at curly braces.

    [05:43 - 05:51] And let's copy all the code from 951. So I'm going to press command X to cut it and paste it inside line 48.

    [05:52 - 05:56] Cool. This means if we're not refetching, then we're loading the data as normal.

    [05:57 - 06:03] I've just noticed status is spelled incorrectly. So let's go ahead and copy this and paste it here to get the correct spelling.

    [06:04 - 06:17] The code spell checker plugin was turned off for a different video and I forgot to enable it for this one. And this is one of the reasons why that plugin is so useful when writing code, because it would have picked up this error before it continued coding.

    [06:18 - 06:28] Now let's go ahead and add a refetching state to our format data response function. Let's scroll all the way down to our format data response function, which should be online 81.

    [06:29 - 06:37] That's actually a delete line 79 since it's adding actual white space. And then at the end of line 82, we're going to enter and write is refetching.

    [06:38 - 06:49] And we'll give that a default value of false. But we also have to change the refetch condition on line 87 to include the ref etching state.

    [06:50 - 07:07] So at the end line 80, let's hit enter and we're going to create a new constant variable called current status, which will equal data cache dot get add parentheses and inside the parentheses, we'll give it a value of key. And then we'll write dot status.

    [07:08 - 07:29] Now that we have current status, we can go ahead and copy that line and all the way on line 88, let's you go below that and then go above it, we can remove the code from status to data cache and we paste it with current status. And then we can also add double ampersands and say current status does not equal a string of refetching.

    [07:30 - 07:42] Perfect. Then let's scroll down to the status response object and we can add a new status below line 97 called refetching, which is going to equal curly braces.

    [07:43 - 07:52] And then we're going to use the spread operator to get the default data. That is refetching to true.

    [07:53 - 07:59] And then write data and pass the payload. Don't forget to add a comma at the end of the line.

    [08:00 - 08:06] Nice. Now that we have the is refetching Boolean, we can add that to our home component.

    [08:07 - 08:19] So at the end of line 11, that's it's enter and right is refetching. And we can copy that and get all the way down to our H one, which should be online 27 and we can create a div above that.

    [08:20 - 08:29] And inside this div, we're going to paste is refetching right double ampersands . And we're going to give a string of refetching with three dots.

    [08:30 - 08:34] Let's make sure to close on curly brace and save the file. Sweet.

    [08:35 - 08:37] Now let's test this in the browser. Wow.

    [08:38 - 08:45] Okay. So we can see that the data is being refetch and keeps refetching in an infinite loop.

    [08:46 - 08:52] Let's go to the sources and pause the script. So you can pause it by pressing this button down here to prevent it from keeping on fetching.

    [08:53 - 09:15] This is because the page first loads with 150 Pokemon, then because the refet on Mount option is set to true, it immediately refetches, which will cause the component to rerender or remout and then another refetch is made and this keeps happening. To stop this, we need to make the data stale after a certain length of time.

    [09:16 - 09:20] Let's say five seconds. And then we refetch only when the data is stale.

    [09:21 - 09:30] Let's go ahead and implement this in our data load of file. Let's scroll up to the prefetch data function, which should be all the way online 30.

    [09:31 - 09:39] And then we can scroll down to where it says, fn, so line 51. And on here on line 52, after it says undefined, we're going to have to comma.

    [09:40 - 09:51] And then we're going to write timestamp and give that a value of date dot now and add parentheses. Our aim here is to give each new data object a timestamp.

    [09:52 - 10:04] So we know the time that was fetch. Then before we refetch data, we can minus the current time from our timestamp and only refetch the data if it's greater than a certain time.

    [10:05 - 10:11] Let's say five seconds. And then when data is refetch, we need to reset the timestamp.

    [10:12 - 10:22] So let's scroll up to our if statement on line 41. And after payload on line 45, we're going to add a timestamp and we'll give that a value of dates dot now with parentheses.

    [10:23 - 10:26] Cool. Now let's go to the top of this file.

    [10:27 - 10:39] And at the end of line three, so at the end of our data cache, we're going to create a new content variable called default stale time. And we'll give that a value of a number, which would be 5000.

    [10:40 - 10:47] Now let's double click and copy on our new variable. And at the end of line 11, we're going to hit enter and write constant is stale .

    [10:48 - 10:53] And this is how we're going to check if the data is stale. What we're going to do is get the current data timestamp.

    [10:54 - 11:02] So that will be dates dot now with parentheses and we'll minus it from the timestamp in our data. So that would be data dot timestamp.

    [11:03 - 11:18] And then we can check if it's greater than the timestamp we've set here on line four, or we can give the user the option to add a stale time. So we can write options, optional chain, dale, time.

    [11:19 - 11:24] And then add the knowledge code lesson operator. Nice, but almost done.

    [11:25 - 11:34] All we have to do is scroll down to line 18 to check when refetching these three made and add another option. So I double ampersand is stale.

    [11:35 - 11:37] Perfect. Now let's go and test this in the browser.

    [11:38 - 11:44] We can unpause the sources by pressing here. And now you can see that data isn't automatically refetched.

    [11:45 - 11:52] Let's go back to the network tab. And now let's click on view details for Charmander and then go back to the homepage.

    [11:53 - 12:01] And we can see that it's refetched the data. It happened so fast that we weren't able to see our refetching text above our H 1.

    [12:02 - 12:14] So whenever we remount this page, so click on view details and then go back, you'll see it does a refet. But if it's under five seconds, then it doesn't do a refetch because the data is not yet stale.

    [12:15 - 12:21] Now of course, because we've set up the option, the user can change the stale time to whatever they want. They can make it 10 seconds.

    [12:22 - 12:25] They can make it one second. They can make it half a second.

    [12:26 - 12:32] But the value of five seconds was used just to demonstrate how stale while we validate works. Nice.

    [12:33 - 12:40] This marks the end of the fourth module of this course. And as usual, we greatly improved our data fetching library.

    [12:41 - 12:44] the next lesson we're going to have a recap of what we've learned so far.