Instructor: In the last section,
we finished up step one
of creating a higher order component.
So we've now written all of the logic
that we want to be reusable into our CommentBox.
Just to be clear,
I wanna point out the code that we want to be reusable.
So inside of CommentBox,
we have componentDidMount, DidUpdate, shouldNavigateAway
and we also have at the bottom mapStateToProps.
Those four chunks of code are the pieces of code
that we need to enforce a restriction
around a user's ability
to access different components inside of our app
if they're not logged in.
So if we have any other component inside of our application
that a user should not be able to access
if they're not logged in.
Right now, we would have to copy paste all this stuff
over to those other components.
Now obviously we don't like to copy paste code around,
we like to make abstractions
and create reusable code wherever possible.
So that's why we're gonna create our higher order component
and so we don't have to copy paste this stuff around.
All right, so I'm gonna flip back over to our diagram.
So we're all done with step number one.
We're now gonna move on to step number two.
So in step number two, we're gonna create a file
to house our higher order component
and we're gonna add some boiler plate code to that.
So I'm gonna flip back over to my code editor
and inside my components directory,
I'm gonna make a new file called requireAuth.js.
Now really quickly here,
you'll notice that I am calling the file with a lowercase r
or I'm naming it with a lowercase leading character
and that's very different
from all the other component files I've created
that have leading capital characters.
So the idea here is that this is a convention
for naming files.
Whenever we use a lowercase r
that indicates that the file is going to export
by default a function,
whereas with any file
where we are naming it with a uppercase character
that means we are exporting by default a class.
Personally, I think it's a silly convention
but that's what it is.
So I'm gonna create this file
and then we're gonna add our boiler plate
or our scaffold code to this thing.
There's gonna be some interesting code in here,
some kind of strange stuff.
So we're just gonna write our code out
and then we'll talk about exactly what it's doing.
I'll get started at the very top by importing React
and the component base class from React
and then I will create
and export an arrow function, like so.
The arrow function is gonna be called
with a single argument,
and we're gonna refer to this argument
as the ChildComponent.
All right, so at this point,
everything might look kind of reasonable, right?
We got an import statement, an export, an arrow function
and even though this argument name is a little bit weird,
whatever, it's an argument.
So here's where things start to get a little bit strange.
Inside the body of this function,
I'm gonna define a new class
with the name of ComposedComponent
and that's going to extend my component based class.
So component right here is coming from React.
Inside this thing, I'm gonna add a render method
that's going to return the ChildComponent.
So I want you to notice right now,
ChildComponent right here
is the argument that got passed into the function.
So ChildComponent, ChildComponent.
Then outside the class, but still inside the function,
I'm going to return the class we just created.
So I will return ComposedComponent like so.
All right, so this right here, this is the scaffold,
this is the boiler plate.
This is the starting code
for creating a ton of different higher order components.
Now, there is one slightly different way
of writing out a higher order component,
and the slightly different way
is what that connect function uses
but either way is totally appropriate.
Just want you to know
that if you go look at other higher order components,
you might sometimes see
a slightly different function signature up here at the top.
Okay, so now that we got the code down,
let's talk about what's going on with this.
So the easiest way to give you a better idea
of what's happening is to write out a little example
at the bottom of the file here.
So I want you to imagine for a second that we take this file
and we import it into our CommentBox file.
So the CommentBox file over there.
So we're going to imagine we are in CommentBox.js.
So we can imagine that inside that file,
we might import the requireAuth higher order component.
So I will import requireAuth from components/requireAuth.
We'll then define that CommentBox
and you know everything that goes on inside of it,
and then here's the interesting part.
At the bottom right now,
we are doing our export default of CommentBox.
I know the connect helper's in there as well
but we'll just forget about that for a second.
So in order to make use of this higher order component,
we're going to take the higher order component
and call the CommentBox with it.
So this is an example
of our higher order component and use right here.
So let's talk about what this really achieves,
what this code right here achieves
along with this code right here.
So the first thing to understand
is that this import statement right here of requireAuth,
this right here is a function.
That's what we're exporting from this file.
Here's the function, we are exporting a function.
So then down at the bottom of CommentBox,
we call that function with the CommentBox class.
The CommentBox class that has its own functionality,
its own methods, all that kinda good stuff.
So we can kind of imagine that CommentBox right here
shows up inside of this function as ChildComponent.
So ChildComponent right here
we can kind of imagine is CommentBox.
I'm just gonna temporarily rename this.
I really encourage you not to rename yours,
just watch for a second.
So we can kind of imagine
that the argument shows up being that CommentBox
and now inside of render,
we'll rename that argument as well to CommentBox.
So what do we have now?
We now have our function being invoked right here.
So we create a new class called ComposedComponent.
All ComposedComponent does is render our CommentBox
and then we return that ComposedComponent class.
So now if someone imported the CommentBox file,
so remember this right here is our imaginary CommentBox.
If we are now imagine, we are in App.js,
we might import CommentBox from components/Commentbox
and what do we get when we do that import?
This import right here.
This variable is going to be the result
of requireAuth with CommentBox.
So when we import CommentBox into our App.js file,
we're not just getting our CommentBox class,
we're getting this composed class right here.
That renders eventually the CommentBox component.
So you can kind of imagine
that this entire system right here
really matches up
with a diagram that we were looking at before
that represented our connect function.
So back over here, I put this little box right here
to represent the connect higher order component.
What these higher order components really do
is kind of wrap or inject themselves
right above the component that we're using them on.
So when we import our CommentBox
as it stands right now into the app,
we are technically importing in that connect component
or the connect higher order component
and that thing inside of it wraps the CommentBox.
So that's exactly what's going on
with this example over here.
If we imagine right here that we import
inside of our App.js file, the CommentBox from CommentBox,
we are getting the result of calling CommentBox
or excuse me, of recalling requireAuth
with the CommentBox component
and that is going to be this right here,
the ComposedComponent class
with our CommentBox inside of it.
So all I'm trying to communicate to you right now
is that by creating this higher order component
and wiring it up inside of our application,
all we're doing with the code as it stands right now
is injecting this extra component into our hierarchy.
That's all that's happening right now.
There's no code reuse, nothing fancy besides that.
All we're doing is injecting another component in there.
Now the trick behind the higher order components
is that now that we have injected this component here,
we can add some reusable functionality to it.
So we're gonna add all of our reusable functionality
to that higher order component, which is now kind of serving
as like a little fake parent to our CommentBox.
So that's what's gonna go on inside of our next step.
Step number three,
we're gonna move all that reusable logic
into our higher order component.
So in other words, we're gonna add all the reusable logic
to this ComposedComponent
and so the ComposedComponent right here is going to know
about whether or not it should try to redirect the user.
It's gonna know how to look at our state object
and pull out that Auth property,
and it's going to know how to access that history prop
and forceably navigate our user around.
All right, so that's my big spiel.
That's basically in a nutshell
what's going on with these higher order components.
So I'm sure that at this point
some stuff is still very unclear which is totally fine.
So what we're gonna do is take a quick break right now
and we're gonna move on to step number three
where we move all this reusable logic
over to the higher order component
and at that point in time,
I think this is going to start to really click.
All right, now the last thing I'm gonna do
is a little bit of cleanup inside this file.
Like I said, this was all just very temporary stuff
that I wanted to put in just to make a point.
All right, there we go.
So let's take a pause right here.
We'll come back to the next section
and we're going to move on to step number three.
So I'll see you in just a minute.