0:00
In today's video, we're going to create this fully functional nav bar in React
0:04
which has active link highlighting and properly refreshes only certain parts of the page
0:08
And best of all, I'm going to show you how to do it using React router and without using any router library at all, so you can truly understand exactly how this works
0:19
Welcome back to WebDev simplified. My name's Kyle, and my job is to simplify the web for you
0:24
so you can start building your dream project sooner. In this video, we're going to create the
0:28
navigation that you see here where you have different links. We can click on them and you can see that the active link is highlighted, same thing with
0:33
the Zabout page, and then we can go back to the home page. Really simple navigation, I'm going to show you how to use React router to create this
0:39
and also how to create it without using any router at all. So to get started, I just have a boilerplate create React application
0:45
I deleted out all the code we don't need and we're just left with a simple H1
0:49
Now to create this really simple navbar, we're just going to create a component for it. We're just going to call this navbar.j
0:54
And in here we're just going to export a default function, which we're going to
0:57
call nav bar and inside of here is we're going to put all of our navigation code and it's going to be
1:02
really pretty straightforward it's just going to be some js xx so we're going to want to have a nav
1:05
element which i'm just going to give a class here that we can use this later so we'll give it a nav
1:10
class and then inside of here i want to have a link for the left hand side so this is going to be our
1:15
site over here that's going to be a link that leads to our homepage just like this and we're just
1:19
going to call it site name you can call this whatever you want also i'm going to give this a class
1:24
so we can style it specifically because i want this to be styled with you know that like
1:28
larger font, so we're just going to call it site title. Then below this, we're going to have
1:32
this list on the right. And generally, when I'm doing a navigation like this, I like to use an
1:36
unordered list. So I'm going to use an unordered list. And inside of here, I'm going to have an
1:40
LI element for each one of the pieces of my list. And inside those LIs, I'm going to have an anchor tag
1:46
And that anchor tag is going to have our H-RF. So for example, we're going to have our pricing page
1:51
And that's just going to say pricing inside of here. And then we're also going to have our about
1:56
page, which is going to say about just like that. Now if we go into our app real quick, we can just render out that nav bar component
2:04
So we can just come in here and say nav bar, make sure that that gets imported at the top of
2:09
our page. And if we save both these files, and we come over here, you can see we have our nav bar
2:13
But obviously it's not styled how we want it to be. And also, it looks like I forgot to put each one of these in our own individual LI
2:20
So let me make sure I do that real quick. There we go. Now they're both on their own LI
2:24
So now what we need to do is actually make this styled correct. So I'm just going to use a simple stylus sheet for that
2:28
I'm just going to import styles.cass. And then I'm going to create that styles.cass file
2:35
And inside of here, the very first thing I like to do is just to set up my box sizing
2:39
So we're going to use border box. And on my body, I'm going to say that there's going to be no margin
2:44
Now with that done, we can work on styling out our nav. It's going to be pretty straightforward
2:48
Let's select that nav element. I'm going to give it a background color here, which is 333, and a color of white
2:53
So the text is going to be white. Next thing that I want to do is I want to make sure I use display flex here, and that's going
3:00
to allow me to space everything out how I want it. So for example, I can justify my content with space between, and that's going to push these
3:07
different elements to the left and the right side of the page. In order to make the links show up, let's just select those anchor tags
3:13
Make sure that the color here is set to inherit. There we go, so we can see those white links, so you can now see they're pushed to the sides
3:20
If I use align item center, that's going to center them vertically, which looks really good
3:24
And then what I can do is I can specify a gap of 2REM and then some padding on the left and right of one REM
3:30
So the gap puts space in between my elements. So if they get too close together, there'll be space between them
3:35
And then the padding is giving me space on the edges so they aren't quite touching the edge of the screen
3:39
Now the next thing I want to do is I want to make it so that these links and such look a little bit better
3:44
So in order to do that, what I'm going to do is I'm going to come down. I'm going to take my nav. I'm going to select the UL itself
3:49
I'm going to get rid of all the padding and the margin that are on here by default. and then I'm going to say that the list style is going to be none
3:55
That's just going to get rid of all the extra spacing and get rid of that, you know, circle on the left-hand side of my different list elements
4:01
That looks really good. Also, I'm going to specify this as a display flex with a gap of one REM, and that's just going to put some space in between these different elements
4:10
Now, if we move down, what we can do is we can actually start styling out our nav itself with this anchor tag
4:14
But also, I want to style out that site title by just increasing the font size
4:19
The two REM, so it was a little bit bigger. Now on our actual anchor tags, text decoration should be none because we don't want those underlines
4:25
That looks a lot better already. And now what I want to do is I want to work on that like active class making that work
4:31
So what we're going to do is we're going to take our nav here. And what I want to do is I want to get the LI that has the active class on it
4:36
I'm going to specify a background color of, whoops, 555. And then on hover I want to have a different background color So if we come over here and we hover this I want to have a background color of 777 Now if I save when I hover over these you can see they get that background color And if I apply that class of active for example to this first L
4:57
you can see that now has a different background color, but you'll notice that the actual height is not quite right
5:02
And also, I should make my active class go above my hover, so that way when I hover the active one, it'll change the background color
5:08
There we go. Now I just need to make sure that this is essentially full height, because right now my link right here is not
5:13
not full height. So we can change this to a height of 100%. Oops, a display here of flex, and we just
5:22
align our items in the center. That'll make sure our text stays in the center, and then we can just give some padding to it, which is 0.25 REM. Now as you can see, that worked a little bit. The only
5:31
thing we have left the change is to make it so that our actual UL element spans the full height
5:35
and we can just do align items of stretch, and that should actually fix that for us, and there we go
5:38
That works perfectly. So now when we hover these, we get this nice highlight effect, and whichever
5:42
everyone's active has that background color being applied to it. So it's like the really basic styles we need
5:47
You could obviously make this look much better. But the real core here is that we have this active class that does something
5:52
So that way we can use that inside of our JavaScript and our React code. So now that we have our Nabbar, what I want to do is I want to create some pages
5:58
And these pages are just going to be the text of home, pricing, and about. So there's going to be separate components that contain all of our code for that page
6:04
So let's create a folder called pages. And inside of here, I'm going to create a new file
6:08
We're just going to call this one, home.j. And inside of here, export a default function called home
6:14
And all this is going to redo is return in H1 with the text home inside of it
6:19
Really super straightforward. I'm going to do that for all of our different pages. So we have here our About page, and we also have our pricing page
6:28
And inside of our pricing page, I just wanted to say pricing
6:31
And instead of Home or about, I want it to say about. So now we have three different components
6:36
One for each of our different pages. I want to render out those components dynamically depending on what page
6:41
we are on. So right now when we click on these links, you can see it refreshes our page and then our
6:44
URL changes to slash pricing. So inside of our app here, we can actually get the URL on our page by saying window
6:51
Dot location. So if I just console log this out, you should see here, if I inspect my page, and bring this
6:59
over, we look at our console. You can see our location here has a bunch of information, but most importantly we have our path
7:04
name which is set to slash pricing. So we can really easily just take this path name and do a simple switch statement over it
7:11
we can say here that we want to do a switch statement and the switch statement is on our window
7:15
dot location whoops location dot path name and here if we have the case where it's just going to be
7:23
the home page we're going to do something specific so i'm going to put that in there with a break
7:28
then what i'm going to do is i'm going to say hey you know what if we're on the pricing page which is slash pricing then we're going to do something else specific and break and then finally
7:38
we have our slash about page. And we're going to have a break here as well
7:43
So now for our different pages, we just want to create a variable. Let's just call it like component
7:49
And it's going to not be equal to anything by default. And what we want to do in here is we're going to say, you know what
7:54
component here is going to be equal to our app. And down here, our component is going to be equal to pricing
8:01
And down here, our component is going to be equal to that about page
8:08
And then we can just render that out. So we'll just come into here. And we're just going to come down and render our custom component
8:18
Now, one thing that is important to make sure that you understand is if you are using
8:22
these custom component that you need to render out by name, you need to make sure you use a capital letter
8:27
Otherwise, it's going to try to render out a normal HTML component, which is obviously a problem
8:31
Otherwise, what you could do is you could say that, you know, you have your app here
8:35
you have your pricing here and you have your about like this
8:40
and we could just call this anything you know it could be a lowercase component in that case let's replace all those
8:45
and then down here we would just render that out like this so either way it's going to work we'll just leave it like this for now
8:50
now what we need to do is import all those pages that we just created so we have pricing um
8:56
and about so now if we come back over in our application
9:01
we have some errors it looks like we'll just clear those out refresh to make sure now those errors exist. As you can see they don't. And now we have our
9:08
pricing being shown. If we go to about, you can see it says about. And if we go to our home page
9:12
if we just give it a second to load here, it shows so this app right here. But it looks like we have
9:17
maybe an infinite loop or something going on. It actually looks like the problem is I just put
9:21
app here instead of home. That is giving us an infinite loop. So now if we just bring this onto a new
9:26
tab, now you can now you can see if I close that, we have our different pages showing up properly
9:31
Now we just need to make it so the active page is actually going to be showing up as the active one Also before we do that I kind of want to put this text inside of its own little container So we can just create a div here with a class name of container
9:44
And then inside of that div we can render out this component. And then we can go back to our CSS here and we can just scroll up to the top
9:50
We can say dot container. What I want to do is I want to give it some margin on the side, top and the bottom
9:57
And I also want to text align it in the center. There we go, because now we have our text dead center
10:02
it just looks a little bit better. So now let's focus again on that active styling
10:06
The first thing that we need to do is we actually need to get that active page. So we can just use this window
10:11
Dot location dot path name inside of our nav bar. They'll go into our nav bar. And we have essentially our path, which is equal to this
10:19
And what we want to do is we want to see if our path is equal to this H-ref right here
10:23
And that's how we're going to add that active class or not. So a really easy way to do this is going to be creating a custom component that wraps our link
10:30
So we're going to do that. We're just going to create a custom component. We'll call it custom link
10:35
Inside of this custom link, we're going to pass it in essentially an H-Ref. So we can just say H-RF here
10:40
And that's all we're really going to care. But we might also pass some custom props. So we're going to make sure we take those into account
10:45
So like if we pass a class name along to here, we're going to make sure that gets taken into account
10:50
So inside of this custom link, we're just going to return essentially our L-I with the link inside of it
10:56
And what we want to do is we want this section right here to be our children. So we can come in here with our children
11:03
And then we have our H.R.F. right here, which is just going to be equal to our H.R.F
11:07
So now I can essentially replace this with our custom link. And that custom link just has the text pricing inside of it
11:15
Oops, if I can spell properly. And it's going to have this H-Ref being passed in as well
11:20
Just like that. And I can do the exact same thing for our About page. So now all I've done is essentially simplify my code
11:27
And the reason I'm doing this is so I can take this path first. I can use that inside of our custom link
11:32
Also, I want to make sure I pass along any other props that we have. But with this path variable, I can determine is this the active path
11:38
Because if our path is equal to our H-ref, then we know that this is active
11:42
So what we can do is we can just take that code and we can say our L.I has a class name
11:47
which is going to be equal to here. If these are equal, then our class is going to be equal to active
11:52
Otherwise, our class is equal to nothing. And with that one simple change, now if we go to our pricing page, you can see that marked as active
11:59
We go to our About page, you can see that's marked as active. So no matter what page we go to, it's always going to be marked as active
12:05
Now, obviously, this is not the most scalable solution. And the main reason for that is if we go back into our app here
12:11
is we get this giant switch statement, which is not the most clean thing in the entire world. And every time we change a page, it actually refreshes our entire application
12:19
When in reality, the only thing changing is this 1H1 right here. The nav bar never changes
12:24
Only the component section changes. So we want to fix all that. And the easiest way to fix all that is by using a right
12:29
routing library such as React Router. So in order to get started with React Router, we're just going to come down into our terminal
12:34
and we're going to install the React Router library. And the React Router library that we want is going to be specifically for the DOM
12:40
So we're going to download React Router DOM, hit Enter, and that's going to download all the libraries that we need for React Router
12:46
If we come into our package JSON, we give this a second, you're going to see right here we have our React Router DOM being installed so we can actually use that
12:53
Now to use React Router, there's a few things that you need to set up. First of all, you need to set up what type of router you're using, and then you need to define
12:59
all your different routes. What we want to do is we want to go into our index page, and here is where we set up our actual router
13:04
that we're going to be using. So we're going to do a quick import here that's coming from that React Router DOM
13:10
And what we want to import is a browser router. And that's just because we're in the browser
13:14
React Router allows you to do routing for things like mobile applications and so on
13:18
But for us, we're creating a web application in a browser, so we're going to be using the Browser Router
13:23
And what you want to do with this browser router is just wrap your entire application
13:26
So we're going to come in here with that browser router, And again, we're wrapping that entire app component
13:31
because our entire component is going to be using this one single router to manage all of the routing
13:36
Now, the next thing we need to do is define that router and all the different routes inside of it
13:40
To do that, we're going to come in here and essentially replace the switch statement with React router code
13:45
So again, I'm going to come up here with an import statement at the top. And this is again going to be importing from that React router DOM
13:52
And I want to import a route. And I also want to import the routes component
13:56
These two components allow us to define all of our routes. and group them together. So for now, we can completely get rid of all of this code right here, because we don't
14:03
need any of this switch statement code, and instead inside of our container where we're rendering
14:06
out our component, this is where we're going to use these two components of routes and route
14:11
So our routes component is going to wrap everything. So we're going to say routes, and it's going to wrap all of our individual routes
14:16
And this routes component essentially just says, hey, here's a list of different routes, choose the one that fits best So we going to define all of these routes as their own route component And each one has a path and this path for our example is going to be like the index page and then it going to have an element And this is the thing it going to be rendering out
14:33
So in our case, we're rendering out our home component, just like that
14:38
And then we can close off that route. So now this is exactly the same as what we had in our switch statement, but it's just handled by React Router
14:44
and they have a bunch of other things that they're going to do along with this. So let's just paste this down a couple times
14:49
So we have our pricing page, and we also have our about page, and our pricing is going to render out pricing, and our about is going to be rendering out the about page
15:00
So now if I save and start navigating around, you're going to notice it actually doesn't change anything
15:03
It still re-renders the entire page, and that's because inside of our nav bar, if we just go to that component, we're using normal A tags
15:10
We need to replace this normal A tag with a link component that is from React router
15:14
At the top here, we're going to be importing the link component from React router DOM
15:20
and this link component essentially replaces our anchor tag. So anywhere that you see an anchor tag, we want to replace this with a link
15:27
Same thing down here, we're going to replace this with a link. But what's really important is that instead of using H-ref, we're using the word two
15:34
Essentially, wherever you have an H-ref inside of this, you're going to replace it with two, and it's going to work exactly the same
15:39
So in our custom links, we're also going to replace these with two. and inside of here we're going to replace all instances of HRF with two
15:46
So now if I save this, you're going to notice when I click on pricing, my whole page doesn't re-render
15:50
just the section that is changing. So if we go back to our app, only the section inside this routes is changing and everything
15:57
else stays the same. So our nav bar stays exactly the same. Our container here stays exactly the same
16:01
And again, only this one section changes and our navigation bar up here at the top changes
16:06
But you'll notice that our actual active classes don't work. And that's because our page never refreshes at all
16:11
So our window dot location isn't really changing. So if we go to our nav bar here, this path right here is not actually 100% correct
16:18
and we can't really rely on this for this. So instead, you need to use React Router's way of handling this
16:23
and they have their own custom hooks you can use to make this work really well. The main hook that you want to care about is the Use Match hook
16:29
but we're also going to be using a hook called Use Resolved Path. So let's make sure we get that Use Match hook and Use Resolved Path
16:35
and I'll tell you exactly why you need both of these in just a second. So Use Match allows us to compare essentially the current path
16:41
that we are on to whatever path we want, so we can compare it to this to property
16:45
And used resolved path, this is really important, because the way the router actually works
16:50
with React router and with normal link tags is you can have absolute paths like this
16:54
which are like absolute, you start with this forward slash and you go to the pricing page, or you can have relative links that say
16:58
you know what, go to the pricing page relative to whatever page you're currently on
17:02
So this use resolved path essentially allows you to take a relative or absolute path
17:07
it combines it with the current path you're on, and gives you the actual full path that you would be accessing
17:11
So we're just going to pass in our 2 property here, which is essentially our URL that we're navigating to
17:17
and we're going to get that resolved path. And essentially, like I said, this converts these relative paths to absolute paths and so on with absolute paths
17:25
It's just going to make sure that your path is the full absolute path, even if it starts out relative
17:30
And then we can determine if this is active. By just saying we want to use that match class, so we could say use match
17:37
And this use math, you can pass it a string, or you can pass it in essentially an object
17:41
And with the object, we want to pass a path, which is our path name for our resolved path
17:46
That's the same thing as like window. Dot location dot path name. And then I want to pass an end of true
17:51
By saying end true, we just essentially are saying that the entire path must match
17:56
Because with React Router, you can actually do like partial matching. And in our case, we want to make sure that the entire URL is exactly the same
18:03
We don't want to worry about partial matching. So this would be useful
18:07
For example, if you had like slash pricing, if our current URL is like slash pricing
18:11
slash, you know, to-dos or something, this would not match because we put n-true
18:15
but if we get rid of the end-true, this would technically match because slash pricing is inside of, you know, if we're at slash-pricings to-do and we're comparing it against
18:23
slash pricing, they both have essentially the same start to the URL, so it could work
18:27
But in our case, we want to make sure we match the entire URL and nothing else excepted
18:31
So if this is active, then we want to add the active class, otherwise don't add it
18:35
So now with that done, you can see our pricing page is set to active. Click on about, now it's set to active
18:39
Click on site name, you can see that that is all working. So every single one of our links is working
18:44
All that all that active class is being applied. And best of all, our page is only re-rendering the section in the middle, the section that actually changes
18:50
and it doesn't re-render all of our other stuff like the navigation up here. And that's all it takes to create a basic React Nav bar
18:57
Now, if you want to take this a step further, you're going to need to learn React Hooks, and I have an entirely free course on React Hooks that I'm going to link down the description for you
19:05
It covers every single React Hook that you need to know. Again, it's completely free and linked down in the description below, so I highly recommend you check that out
19:12
With that said, thank you very much for watching and have a good day