React Router NavBar example with NavLinks
In this example we improve the NavBar, pulling it out into it's own file and using React Router's NavLink component. We've also added styled-components
and show how you can restyle React Router's NavLink.
NavBar implementation with Flexbox
To start, we'll declare an outer container NavBarOuterContainer with some vertical margin. Inside this component, we'll add a component called NavBarInner which will be using Flexbox by declaring display: flex
.
Inside the NavBarInner
, we'll add two top-level components representing a list of NavLinks on the left and on the right. On the left, we declare LeftNav
with flex-grow: 1
, meaning it will stretch the entire width that it can. This will allow us to fill as many items in the left nav as we want, and still stretch the entire width to leave a space between itself and the right nav item (just one NavItem on the right).
Additionally, we declare the LeftNav
a flexbox with display: flex
as well, so that we can stack items horizontally. Inside of the LeftNav
, we target any NavItem
and add a margin-right: 10px
to it, so only LeftNav items will have margin on the right, which gives some padding between LeftNav items. We're not adding additional items to the right nav, so we just use a single NavItem as the second top-level navigation link, and that will suffice for now.
Let's discuss the NavItem component.
The NavLink Component
The NavLink is similar to React Router's Link component except that it adds a special class active
when the current location matches the path of the Link. This is useful for when you want to add styling on a navigation link to indicate the user is on the current path.
A CSS Class selector with Styled-components
Take a look at the NavItem component that we declare by wrapping React Router's NavLink
with the styled
helper from styled-components. Observe that we declare two props first to override the browser's default link styles (a blue text color and underline).
We then declare a selector when &.active
, meaning when the component has a CSS class of active
, apply the styles below. We apply a border-bottom of 1px solid black
in this case.
End prop
You may notice that the Home link has an additional prop of end
. If the end prop is used, it will ensure this component isn't matched as "active" when its descendant paths are matched. Without this prop, Home link will always think it is matching the other paths.
import styled from "styled-components"; import { NavLink } from "react-router-dom"; const NavBarOuterContainer = styled.div` margin: 20px auto; `; const NavBarInner = styled.div` display: flex; `; const NavItem = styled(NavLink)` text-decoration: none; color: black; &.active { border-bottom: 1px solid black; } `; const LeftNav = styled.div` flex-grow: 1; display: flex; ${NavItem} { margin-right: 10px; } `; function NavBar() { return ( <NavBarOuterContainer> <NavBarInner> <LeftNav> <NavItem to="/" end> Home </NavItem> <NavItem to="missions">Missions</NavItem> <NavItem to="logs">Logs</NavItem> </LeftNav> <NavItem to="account">Account</NavItem> </NavBarInner> </NavBarOuterContainer> ); } export default NavBar;