Saving Data Sources

This lesson, focus on saving and reusing prefetched data sources efficiently using context and a custom data-loading function.

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:11] This is the final issue we have to fix before we can implement stale while we validate, saving prefetch data sources. But first, let's talk about why we want to do that.

    [00:12 - 00:22] Let's take a look at the code in our app. Right now in the main.jsx file, we have a function here on line 13 that will prefetch all the Pokemon data.

    [00:23 - 00:40] And if we look at our home component, we have a similar function inside the use data hook, so over here where we have get Pokemon and the random limit argument. This function is used to make the refetch button all the way down here, on line 22, to fetch data when it's clicked.

    [00:41 - 00:56] But imagine if we scroll up to line 9, imagine if we didn't want to change the amount of Pokemon fetch each time we clicked and we just wanted to refetch the default 150. That would mean this code here seems like an unnecessary duplication.

    [00:57 - 01:10] Let's talk about how we can fix this. What happens right now when the main.jsx file loads, so when I upload, it gets the functions from our data sources, makes the fetch calls and saves the data inside the data cache.

    [01:11 - 01:36] So if our home page leaves data, it goes to our data load function, and then our data loader gets the data from the cache. But if we didn't have any data in the cache, or we wanted to update the data in the cache, when we clicked on the refetch button without a callback argument, then our data loader code wouldn't know how to refetch that data, since it doesn't have access to that function anymore, which is inside our main.jsx file.

    [01:37 - 02:00] So if we wanted to fix that, what we could do is get the data sources from our main.jsx file, including the functions, and save all of that inside our data cache. This means that whenever we want to refetch the data without a callback function, because the callback function is saved inside our cache, we can just call it again, which will make the fetch to an external source and save the data in the cache.

    [02:01 - 02:06] I hope that makes sense. Let's go ahead and implement this inside our data loader file.

    [02:07 - 02:33] Beneath our data cache variable, so at the end of line three, let's create a new variable called preloaded data sources, and this is going to equal an empty array. Now let's scroll down to our pre-fetch multi function all the way online 52, and at the end of line 52, we're going to hit enter, and assign our preloaded data sources function to the data sources argument that's passed into this function.

    [02:34 - 02:43] Cool. Now the data sources array from the main.jsx file is saved in memory, and our data loader file should have access to them.

    [02:44 - 02:59] Scroll to the bottom of this file, press enter a few times, and on line 85, we 're going to create a new function called fetch or use preloaded data. This is going to have two arguments, one of key and one of function.

    [03:00 - 03:21] Basically, what this function is going to do is check our preloaded data sources array to find out if the key we pass in as an argument has a matching data source. If it does, then we can run the prevex data function with that key and the pre loaded data source, or we could use the function that's passed into this argument.

    [03:22 - 03:37] I know this sounds confusing now, but it will make much more sense when we start writing code. So let's open up this function and we'll create a new constant variable called preloaded data source, and this is going to equal our preloaded data sources variable.

    [03:38 - 03:57] But we're going to use the find method to find a data source that has the same key, so we'll write data source dot key as the key we pass into this argument. And then we're going to run the prevex data function with an argument of the key that's passed in and the argument of the function that passed in.

    [03:58 - 04:06] But if no function is passed in, then the keys the function from our preloaded data source. So we're going to use optional training and then write fm.

    [04:07 - 04:11] Cool. Now, let's update our code to make use of this new function.

    [04:12 - 04:24] First, I'm going to double click on the function name and press command C to copy it, then scroll up all the way to our refetch function over here. And we're going to change prevex data on line 72 with our fetch or use pre loaded data.

    [04:25 - 04:35] Let's also scroll up to the prevex on event function, which is on line 47. And let's change prevex data on line 49 to fetch or use preloaded data.

    [04:36 - 04:44] Finally, let's scroll all the way up to our use data hook. And on line six, if you have it, let's remove the default value in fm since it could be undefined.

    [04:45 - 04:54] Now, let's test this by changing the code in our home component. On line nine, let's remove all the code from the second argument, just leaving the Pokemon's key.

    [04:55 - 05:01] And also, let's make one small change to the details component. Let's scroll all the way down to line 15.

    [05:02 - 05:12] And here on the link that goes back to the home page, let's pre fetch Pokemon data on hover. So here we can write on mouse enter, or make that equal curly braces.

    [05:13 - 05:19] And then we'll give it an arrow function. And inside this arrow function, we're going to write prevex on event.

    [05:20 - 05:27] And here we'll give it an argument to be a string of Pokemon's. Notice here that we haven't added an argument to fetch the data.

    [05:28 - 05:31] Now let's save this file and test it in the browser. Cool.

    [05:32 - 05:47] So if I press this refresh button, you'll see that it refetches 150 Pokemon each time I press it. And if I click on the view details button and refresh this page, then hover over the back button, you can see that it also fetches 150 Pokemon.

    [05:48 - 05:58] This will reduce the amount of duplicated code that we have in our code base. But of course, if you still wanted to add a specific amount, you could go ahead and add the function back into the use data hook.

    [05:59 - 06:01] Let's demonstrate that. Add the home component.

    [06:02 - 06:08] I'm going to press command Z to bring the code back, then press command F to save. Now let's go back to the browser.

    [06:09 - 06:18] If I go to the home page and press the refresh button, you'll see that it refet ches a specific Pokemon amount. Now with this change, there's one more really cool thing we can do.

    [06:19 - 06:27] Let me show you by going to the main.jsx file. If we take a look at our data sources, right now, we're prefetching the code for the details page.

    [06:28 - 06:33] But what if I didn't want to do that? What if I wanted to only load the data once the component starts loading?

    [06:34 - 06:44] A bit like how use effect works, but slightly more efficient. This sounds a bit odd, but it may sometimes be easier to put data fetching logic inside the component.

    [06:45 - 06:58] So let's remove all the code from 920 to line 16 and we'll keep everything the same. This means that if we open the browser, went to the details page and refreshed, it wouldn't fetch any data.

    [06:59 - 07:05] Let's go into the details component and address this. On line nine, that's first copy all the code inside the parentheses.

    [07:06 - 07:26] And at the end of line eight, we're going to create a new constant called name and we'll sign it to that code. Now on the new line 10, we're going to delete all the code inside this parentheses and we'll give the use data hook a first argument of name and a second argument of an arrow function, which will run the get Pokemon details function with an argument of name.

    [07:27 - 07:43] Now before you go ahead and test this in the browser, there are a few changes we have to make inside the data load of file in order for this to work. At the end of line 10, as it's enter, I'm going to add an if statement to check if data.status is equals to the string of idle.

    [07:44 - 08:06] If the status is idle, this means that no data is being fetched because if data is being fetched, it will have a status of loading. So if no data is being fetched, then that means we can either go ahead and get the fetcher function from the data sources in our main.jsx file or get the function from an argument that's passed into our hook.

    [08:07 - 08:17] Luckily, we've created a new function to help us decide on what to use. So let's add some curly braces and online 12, we're going to make use of our fetch or use preloaded data function.

    [08:18 - 08:27] And here we'll pass into arguments of key and function. This creates some space, so at the beginning of line 11, I'm going to hit enter and also at the end of line 14, I'll hit enter as well.

    [08:28 - 08:42] Now we can go ahead and test this in the browser. So let's click on the details button for Venusaur, then refresh the page and you'll see that it fetches data for the correct Pokemon, even though that the fetcher function wasn't inside the main.jsx file.

    [08:43 - 09:00] This is because our logic looks for the function that's passed in as a second argument in the use data hook and if there isn't one there, it's going to use the function from our preload data sources. But because we have one in the details page, then it uses that function.

    [09:01 - 09:04] Very cool. Our data loading library is getting more powerful.

    [09:05 - 09:10] And in the next lesson, we're finally going to talk about a caching technique called stale while we validate.