Check out a free preview of the full Complete Intro to React, v3 (feat. Redux, Router & Flow) course:
The "Async Routing" Lesson is part of the full, Complete Intro to React, v3 (feat. Redux, Router & Flow) course featured in this preview video. Here's what you'd learn in this lesson:

Brian sets up an async route, which is a higher-order component that displays a loading state until a component is completely loaded. Once the targeted component is loaded, the AsyncRoute will remove the loading state and display the component.

Get Unlimited Access Now

Transcript from the "Async Routing" Lesson

[00:00:00]
>> Brian Holt: What I want you to do is the first thing that we're gonna have to do, is we're gonna have to create a component called an async route. So create a new component inside of JS. And don't get me wrong, other people have written libraries that will do this for you, but I wanted to show you that there's nothing scary here, you can do this all yourself.

[00:00:22] So create a component called AsyncRoute.jsx inside of your JS directory. Make it a flow component, import React from React.
>> Brian Holt: And also you're going to need component.
>> Brian Holt: And we're gonna import Spinner as well because we're gonna want a little nice loading spinner. From ./spinner. Okay. And then we're gonna have class AsyncRoute extends component.

[00:01:05]
>> Brian Holt: And then at the bottom you're gonna have to export default AsyncRoute. Okay. So this is the first higher order component that we're gonna write. So Async@Route itself, I guess can render its own markup, because sometimes it'll render Spinner for us. But it's actually capturing a behavior, right?

[00:01:26] What it's going to do is when it's rendered, it's going to go out and fetch the component that you asked for, and then only after that it fetched it that it's going to render itself, does that make sense? Cool. So it's gonna take two things in, two props.

[00:01:45] It's gonna take the props that you wanna pass to the component. And then the second thing it's going to take is a loading promise, right? So let's take a look what that looks like. And it's also gonna have a state of whether or not it's loaded, right? So, by default it's not going to be loaded, right?

[00:02:06]
>> Brian Holt: Then we're gonna have props in here, which is going to take in two different props. One's gonna be mixed, so we don't know or care what are in the props, right? We're just gonna take the props that they give us and pass it down to the component.

[00:02:22] So props is gonna be mixed, that's what we're kind of asserting there. And then loadingPromise is going to be of type promise, right? But with promises you actually have to give it what the promise is going to return, right? Remember how we did parameter with types?
>> Brian Holt: So it's going to give us back an object, and the,

[00:02:54]
>> Brian Holt: The default parameter inside of this object is going to be a React component, right? So it's gonna be a class of React Component, React.Component
>> Brian Holt: And then let's not get too far into the weeds about how React is typed. But React has three different props that you pass to React components.

[00:03:18] We're not gonna validate what those are because we don't know what kind of React components it's gonna be. So you're just gonna say *,*,*. I do believe that this is default props. Props and state are the parameters there. I usually don't care, right? So, sufficed to say, just believe me that this is okay.

[00:03:37] Cool? Cool.
>> Brian Holt: Oops, that needs to be on the other side. No. Well, I guess that-
>> Speaker 2: You need one of each, don't you?
>> Brian Holt: Yeah, I think I need that. There we go.
>> Brian Holt: So I realized this is kind of a lot right here, so let's just talk about it one more time.

[00:04:06] This is a promise, right? A loading promise is a promise. What that promise returns when it resolves is an object, right? Inside of that object, this is what's gonna come back from Webpack when it loads your code asynchronously. it's gonna be an object with a default property on it, right?

[00:04:25] And that default property is going to be a class, like this sort of class, right? And the type of class that it is is a React component, right? And React components can be typed in various ways that we're going to ignore for now. That's what the stars means, it means I don't care what they are, right?

[00:04:42] I don't care what type of React component it is, I just know that it's going to be something that React can render. Good, cool? All right.
>> Brian Holt: So something that we could do, we could store the component here in state. This is a bad idea. The reason why this is a bad idea is, if you remember React when it's doing it's diffing algorithm it's going to be checking everything inside of your state.

[00:05:11] A React component has a lot of stuff on it, and we don't actually want React to be going through that ever single time it does a re-render. So a good way to side step that is just to say, I'm gonna put component on the class itself. If the component lives on the class itself, or anything lives on the class itself, React doesn't check that.

[00:05:31] So it's diffing algorithms is not gonna put its tendrils in there, right? Which we don't want it to. So that's why we're going to put it on the class and not necessarily in state. Does that make sense? Only keep things in state that have to do with rerenders, right?

[00:05:46] If I change the loaded from true to false, I need a rerender right there. Component is never going to force a rerender, right? We're gonna load the component once and then not do anything more with it. So it's good to put that on just the class itself. Okay?

[00:06:04] Now between these two, I need to create a componentDidMount. As soon as this component is mounted to the dom, we wanna go and start requesting, or sorry, we actually wanna be acting upon this promise that we'll gonna get from props, right? So what we're gonna say right here is this.props.loadingPromise,

[00:06:31]
>> Brian Holt: And we're gonna say .then. It's gonna take in a module that Webpack is going to give us
>> Brian Holt: And then we're gonna say this.component,
>> Brian Holt: = module.default. Then at that point we're gonna say this.setState loaded is true.
>> Brian Holt: Okay? So it's gonna be passed in a promise.

[00:07:11] When that promise resolves, it's gonna get that module from Webpack, right? This can happen immediately, right? If I go from details to search, then back to details. Details is still going to be in Webpack's cache, and it's just going to immediately resolve that promise for me. But this'll still work in either scenario.

[00:07:34] So this.component is going to be equal to module.default, right? We know that that's going to come back because we created that type right here. So that's why that plays nicely with flow. And once that's been loaded, we´re gonna set it loaded to true, okay? Last thing we need to do here is create the render function.

[00:07:59]
>> Brian Holt: And it's just gonna be a, if this.state.loaded so if I'm loaded, then I want you to return this.component and then I wanna just pass whatever props into that. This.props.props. I know this look weird, right? But we have a props called props, right? So, that's what you end up with.

[00:08:32] If I don't have a state being loaded yet. What I'm going to return is spinner. I'm gonna return some sort of loading UI, right? In this case, we're just gonna put the big Spinner on the page.
>> Brian Holt: And that's it,
>> Brian Holt: Any questions about this?
>> Brian Holt: So now we have this Async Route component.

[00:09:03] That we can use inside of our router so that it's only going to load components when they're only when they're needed.