‫Let's now learn about React Router's
‫powerful new data loading feature,
‫which is called loaders.
‫So the idea behind a loader is that somewhere in our code
‫we create a function that fetches some data from an API.
‫We then provide that loader function to one of our routes
‫and that route will then fetch that data
‫as soon as the application goes to that route.
‫And then in the end, once the data has arrived,
‫it will be provided
‫to the page component itself using a custom hook.
‫So that sounds a bit confusing.
‫And so let's actually implement this with code.
‫And I want to start by fetching the menu data.
‫So again, we do this in three steps.
‫First, we create a loader.
‫Second, we provide the loader, and third,
‫we provide the data to the page.
‫Now, this data loader can be placed anywhere
‫in our code base
‫but the convention seems to be to place the loader
‫for the data of a certain page inside the file of that page.
‫So here in this case, we want to load the menu data.
‫And so let's go to this component
‫and create the loader function right here.
‫So again, the convention here
‫is to just call this function a loader.
‫And so then here, this function needs to fetch the data
‫and then return it.
‫Now, where are we actually going to get that data from?
‫Well, that's where the restaurant service
‫now comes into play.
‫So let's open up this file.
‫And you see that here we have multiple functions.
‫So we have getMenu, we have getOrder based on an ID,
‫we have createOrder, and we have updateOrder.
‫So if you want, you can take a look at all of this code
‫but this is just some pretty standard code here.
‫What matters is that this is the API URL, which again
‫is that API that the React Fast Pizza Company already has.
‫So it is here in this URL, and it might change
‫by the time you're watching this video.
‫But then I will just update this file.
‫So just to see the data, let's grab that URL, go here
‫and then /menu.
‫And so then that should load.
‫And indeed, here is all the data for our menu.
‫So here that's this /menu right there.
‫And so all we need to do now
‫in that loader is to call this getMenu function.
‫All right, so basically,
‫we abstracted this function right here
‫into the service
‫so that now we can use it inside our loader functions.
‫And of course, we could also place
‫all this logic right there in the loader as well.
‫But it's a lot better to have this kind
‫of logic here in a central place also
‫because this might be necessary in some different places.
‫And also because then we centralize also the API_URL.
‫So it's nice to abstract this logic away here.
‫So into that service.
‫And then here, all we need to do is to call that function.
‫So let's then save the result into a variable called menu.
‫And then here we await calling getMenu.
‫So this is then an async function
‫that we also need to export.
‫And so now here we have the default export
‫for the component itself,
‫and then we also have a named export
‫for the loader function.
‫But that's no problem at all.
‫And now all we need to do is to return the menu.
‫And we could have done this all in one line, but like this,
‫it's a bit more explicit.
‫So the loader function needs to return
‫whatever data it wants to provide to the page.
‫Okay, and now let's do the second step,
‫which is to connect the loader function to the route.
‫And so that function,
‫so that loader is here in this component.
‫And so in order to import now the named export,
‫we do it like this, and then let's actually rename it
‫because otherwise, we will later end up
‫with multiple loaders.
‫So let's say loader as menuLoader.
‫So this is how we rename some named exports
‫or named imports here in this case.
‫And so here we can now specify the loader property
‫and then specify the menuLoader.
‫Okay, give it a save.
‫And so with this, we completed step number two.
‫So we now provided this loader function to the menu route.
‫And now all we have to do is to get that data
‫into the component.
‫And so as I mentioned earlier, for that,
‫we can use a custom hook, which is called useLoaderData.
‫And here we don't have to pass in anything into the function
‫because React Router will, of course, automatically know
‫that the data that we want here is the one
‫that is associated to this page.
‫And so that's the data coming from this exact loader here.
‫So let's then call it menu.
‫And for now just log it to the console.
‫So let's give it a save.
‫Let's open up here actually our network tools.
‫So this is pretty small
‫but I can't make it too big as well.
‫But yeah, so let's just reload here just to make sure.
‫Then I will clear everything.
‫And then let's move to the menu by clicking here.
‫And indeed, you see
‫that a new fetch request was fired off automatically.
‫And if we then check out our console,
‫then indeed, here we have our menu data.
‫Beautiful. So this worked.
‫And so we successfully connected this loader function now
‫to this page.
‫And effectively what we just did here was to implement
‫or to use a render as you fetch strategy
‫because the nice thing about this
‫is that React Router will actually start fetching the data
‫at the same time as it starts rendering the correct route.
‫So these things really happen at the same time,
‫while what we did before using useEffect was always a fetch
‫on render approach.
‫So basically, we rendered the component first,
‫and then after the component was already rendered
‫is when we then would start to fetch the data.
‫And so that would then create
‫so-called data loading waterfalls, but not here.
‫So here everything really happens at the same time,
‫which is a really nice
‫and really modern thing to do as well.
‫So with this, what we just did,
‫React Router is no longer only responsible
‫for matching component to URLs in the browser
‫but to also provide the data that is necessary
‫for each page.
‫So again, in this case, for providing the menu data
‫using the menuLoader to the menu page here.
‫And this is really useful because URLs pages
‫and the data that pages require
‫are very often tightly coupled together.
‫And so it is really practical
‫in these situations to get both the page
‫and the data all in one place.
‫So all nicely integrated within React Router.
‫But anyway, now that we know how this works,
‫let's then actually do something with the menu here.
‫So let's create one ul where we then loop over the menu.
‫So .map.
‫And then here, each item of the array is a pizza.
‫And for each pizza, we want to render this menu item here.
‫So here I see we have another error.
‫So let's just automatically import that here.
‫And then here, notice how this menu item,
‫all it does is to receive one pizza object.
‫So that's basically one of these objects
‫that we have here in the menu.
‫So MenuItem.
‫And here we pass in the current pizza
‫and the ID or actually the key.
‫So never forget the key in a map like this.
‫And so here, let's use pizza.id.
‫All right, give it a save.
‫And it is actually already working.
‫So again, there's no styling.
‫But here we have our menu with all these beautiful images.
‫And yeah, again, this data is coming from React Router
‫or at least it is being injected
‫into this page using React Router.
‫Now, you could, of course, argue
‫that this is no different from what we have doing before.
‫So we still have this function here
‫right inside the component file.
‫And so this might look very similar
‫to simply fetching the data right in the component.
‫So basically, just doing that data fetching here
‫right inside a useEffect here in the component.
‫However, as I mentioned earlier,
‫this is actually using the render as you fetch strategy,
‫so not the fetch on render that creates waterfalls.
‫Also, as I mentioned in the beginning,
‫this function here really could be placed anywhere
‫because what matters
‫is that the data fetching logic is actually centralized here
‫in the route definition.
‫So the data fetching really is fired off right here
‫in the router itself, not in the component.
‫And so if all of these components here
‫would be fetching some data,
‫then all of that would be happening here in this one place,
‫which is something that we always strive for.
‫So it's always good to have all the data loading
‫and really many other things
‫as well happening just in one place,
‫so that we can see what's happening all at once.
‫But anyway, after this long explanation
‫of how data loading works in modern React Router,
‫let's also use these capabilities
‫to display a loading indicator right
‫in the next video.