Fetch Data Before you Component Loads
We will learn how to fetch data before the component loads
Get the project source code below, and follow along with the lesson material.
Download Project Source CodeTo 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.
- |
Lesson Transcript
[00:00 - 00:10] The first thing we're going to focus on when it comes to data fetching is fetch ing before the component loads. This is also known as pre-veguing.
[00:11 - 00:32] The reason for doing this is because as we've discussed the use effect hook will only run after the component has been mounted which means the component will always render first before data fetching begins. For the most part, if your users have a decent internet connection and your app is small, they may not notice any issues with performance.
[00:33 - 00:48] But if you have a large app or users have a slow internet connection, then you 'll want to squeeze out every bit of performance you can. Therefore, if the data starts fetching before the component mounts, then the data loading process has a head start.
[00:49 - 01:02] Let's go through how we can do this using a simple Pokemon List app. If you want to work locally, you can get the code for this app in the lesson notes, and if you're using the new line IDE, then you don't have to do anything.
[01:03 - 01:08] The code should just be there. Let's take a look at the Pokemon List app running in the browser.
[01:09 - 01:19] The app is fetching data from the POKI API with the use effect hook and is displaying the data here. If we click on the view details button, it shows details for a specific Pokemon .
[01:20 - 01:30] I've added a few console logs to the project to trigger when the component mounts and when the data is fetched. Let's go back to the home page and take a look at these console logs.
[01:31 - 01:43] We can do that by right clicking anywhere on the page and clicking on the inspector link. Let's change the tab from Elements to Console and to get rid of all this data, let's refresh the page by pressing Ctrl or Command R.
[01:44 - 01:50] Nice. Over here you can see the component loads first before the data loads.
[01:51 - 01:56] Don't worry about the console logs appearing twice. We'll talk about why that happened later on.
[01:57 - 02:05] Let's take a look at the code for this application. The aim with this project is to use as little dependencies as possible so that we can focus on data fetching.
[02:06 - 02:21] So if we scroll down in the package JSON and have a look at the dependency section, we can see that there's just React and React DOM. So that in the dev dependencies, this is everything that's automatically provided by the VteReacts template.
[02:22 - 02:31] I don't want to spend too much time going through the code structure but we'll quickly go through some of the folders. Let's start with the source folder.
[02:32 - 02:40] Here you can see there's a root and a link component which is used for basic routing. Feel free to take a look at how they work if you get some time.
[02:41 - 02:46] It's really cool. Next is the home component which is the home page of the Pokemon app.
[02:47 - 03:00] There's honestly nothing special about how this works but it does have two console logs here on line 11 and here on line 15. This triggers before the data starts to load and this triggers when the component loads.
[03:01 - 03:18] You can see that even though the console log on line 15 is after line 11, this one still triggers first because effects run after the component has loaded. I've noticed on line 10 looking at the arrow function I forgot to turn font lig atures on from a previous video.
[03:19 - 03:28] So I guess for this course it's going to run with font ligatures turned off. But of course if you're working with the code locally, you can turn font lig atures on.
[03:29 - 03:36] Now let's go back to the code. Next there's the details component which just contains the details for a specific Pokemon.
[03:37 - 03:49] Each one of these components has their own CSS module file which is used to style the components. Let's take a look at the API folder and we can see there's just one file here called Pokemon.js.
[03:50 - 03:57] This file contains the logic for fetching Pokemon data. Now let's quickly take a look at the main.jsx file.
[03:58 - 04:09] As you can see on line 7 and line 9, the app component is wrapped around a React component called strict mode. This is a built-in component that checks for potential problems in your app.
[04:10 - 04:15] It's used in development but not included in production. But this is the cause of the double console logs.
[04:16 - 04:31] In strict mode, a React component mounts once, then checks for errors, then renders again to show the app. If it removes strict mode so we can select the code on line 7 and delete it and also on line 9, then press command S to save and go back to the browser.
[04:32 - 04:40] We can see here that in the console, the logs only appear once. Let's go back to the code to put strict mode back since it's good to have.
[04:41 - 04:55] So in the main.jsx file, I'm going to press command Z a few times until strict mode is wrapped around the app component. Now that we've had a brief overview of the code structure, let's go ahead and start fetching data before a component loads.
[04:56 - 05:06] Since we know we're going to need data for the home component, we can start fetching that data before the home component loads. We can do that in this file by running the get_pokémon function.
[05:07 - 05:20] So at the end of line 4, let's it enter a few times and run its get_pokémon and in the dropdown, let's pick the second option and VS code should automatically import that from our API file. Let's add parentheses and close with the semicolon.
[05:21 - 05:28] Now if we ran this in the browser, then this API call will be made before the home component loads. But there's a problem.
[05:29 - 05:44] If we go to the home component, we'll see that inside the effect hook, so here in line 12, we're fetching the data and then setting it to the Pokemon reactive state value. So we need to find a way to set it to this component state once the data is fet ched.
[05:45 - 05:48] And we can do that with a custom hook. Let's think about how that could work.
[05:49 - 06:05] So we need to trigger a fetch before the component loads inside our main.jsx file and inside the home component, we need to set the state once the data is fetched. But fetching might not be complete when the component loads, which means the component will just show loading text.
[06:06 - 06:20] So we need to find a way for our custom hook to listen for when the data is fet ched and only set the state once it has proper data. Also, when the data is fetched, we need to store it somewhere so that we can use it in the hook.
[06:21 - 06:25] Okay, that's enough discussing. Let's go ahead and implement this in the code.
[06:26 - 06:44] Let's open the file explorer and inside the utils folder, we'll open that up, right click, go to new file and we'll create a file called data dash loader dot js. And inside this file, let's write export function and we're going to call this function use data.
[06:45 - 06:50] As you've guessed, this is going to be our hook. Let's add parentheses and add curly braces.
[06:51 - 06:56] We'll keep it empty for now. Above this function, let's create a variable called store.
[06:57 - 07:06] This is going to be assigned to an empty array. Now in order to make our hook listen for when data is fetched, we'll use a custom event listener.
[07:07 - 07:16] So in our hook, we'll first create a use data hook to store the data. Let's write const, add square brackets and write data, comma set data.
[07:17 - 07:25] And this is going to be equals to the use state hook. Make sure online one, it's automatically imported from react.
[07:26 - 07:35] Let's add parentheses and we'll give this a default value of not. Then we're going to add a native JavaScript event listener that will listen for when the data is fetched.
[07:36 - 07:48] This uses the observer pattern under the hood. At the end of line six, hit enter and write window dot add event listener will select the first option from the drop down, then add parentheses.
[07:49 - 07:57] And inside the parentheses, we're going to add a custom event, which we'll call data fetched. But of course, you can call this whatever you want.
[07:58 - 08:09] Then once we have the data, we're going to run a function that will call a set data function. And inside the parentheses, we're going to pass it the value of store.
[08:10 - 08:22] So basically what this line is doing is setting the data from the store inside our data reactive variable, online six. By this point in the code, so online seven, there should be data inside our store variable.
[08:23 - 08:31] Then once we have the data, we can just return it. So at the end of line seven, hit enter, writes return, and then we can return our data variable.
[08:32 - 08:33] And that's it. Cool.
[08:34 - 08:44] So we have an event listener, but we need something to trigger the event. Let's create a new function below our use data hook called prefetch data, which will take a function as an argument.
[08:45 - 08:57] At the end of line nine, hit enter, and we're going to write export function prefetch data that add parentheses and add curly braces. Let's make sure inside the parentheses, we write an argument of FN.
[08:58 - 09:19] Since the function that's going to be passed in will most likely be a promise, we can use the then method to store the data and trigger an event. So inside the curly braces, let's hit enter and write FN add parentheses and then use then methods with parentheses and inside these parentheses, we're going to write another set of parentheses, which will give an argument of data.
[09:20 - 09:28] And then we'll add an arrow function, add parentheses. And here we're going to write store equals data, which puts the result of the promise inside the store variable.
[09:29 - 09:49] Then we'll hit enter and write window dot dispatch event, then add parentheses and inside these parentheses, we're going to write new event, add another set of parentheses, and here we can put the name of the event. So let's double click on data threats from line seven and we'll paste it inside the event argument.
[09:50 - 09:56] Nice. Let's add a semicolon at the end of line 14 and at the end of line 15 as well.
[09:57 - 10:07] Now let's go back to the main dot JSX file. And here we can make use of our prefetch data function by passing in the get_ percomons function as an argument.
[10:08 - 10:18] So at the end of line seven, we can delete the semicolon and the parentheses. And at the beginning of line seven, we can write prefetch data, let's add the space and then write that again to make sure it's being imported in VS code.
[10:19 - 10:27] So we'll write prefetch data. And here we can add parentheses and at the end of line eight, we can add a closing parentheses with a semicolon.
[10:28 - 10:32] Cool. Now let's make some changes in our home component.
[10:33 - 10:41] Once we're getting the data from our store, we can get rid of all the code from line 13 to line 10. And we can also get rid of all the code on line eight.
[10:42 - 11:01] And on line eight, we can write const per commands equals use data and add parentheses. What we can also do at the end of line nine is write a console log and then in the parentheses, we can write per commands and then give a second argument of data fetching.
[11:02 - 11:13] Cool. So the code on line 10 will trigger when the component first loads and also when the data is fetched, meaning if our custom event list is working, we should see data in our console log.
[11:14 - 11:21] Let's now go ahead and test this in the browser. If we refresh the page, we can see we have data in our Pokemon list.
[11:22 - 11:34] And if we scroll up to look at the console logs, we can see here that data starts being fetched before the component loads. These two console logs run again because of the strict mode wrapped around our app component.
[11:35 - 11:42] And then when the data has been fetched, our data fetching log triggers again and the component rerenders. Nice.
[11:43 - 11:48] This is really cool. We're actually loading data into our application without the use effect hook.
[11:49 - 11:57] But there's a problem. If we click on a button to view a Pokemon and then go back to the homepage, you 'll see that data isn't being fetched again.
[11:58 - 12:07] This is because data is only fetched once in the main.jsx file. But there's actually no need to fetch the data again since we already have it in our store.
[12:08 - 12:16] So we need to find a way to check if we have data already in the store. And if it is, we can make use of that data.
[12:17 - 12:19] This is also known as caching, which we'll talk about in the next lesson.