Using the Link and NavLink Components to Navigate to a Route
React-Router provides the <Link> and <NavLink> components, which allow you to navigate to different routes defined in the application. These navigation components can be thought of as being like anchor links on the page that allow you to navigate to other pages in the site. In a traditional website, when you navigate through the application using anchor links, it results in a page refresh, and all the components in the page are re-rendered. Navigation links created with <Link> and <NavLink> do not result in a page refresh; only those certain sections of the page that are defined using the <Route> and that match the URL path are updated.
The <Link> component
A <Link> component is used to navigate to an <indexentry content=" component:about"> existing route that is defined using the <Route> component. To navigate to a route, specify the pathname used in the route as a value to the to prop:
import { Link } from 'react-router-dom';
classAppextendsComponent {
render() {
return (
<div class="container">
<nav>
<Link to="/">Home</Link>
<Link to="/dashboard">Dashboard</Link>
</nav>
<Route
path="/"
component={HomeComponent}
exact
/>
<Route
path="/dashboard"
component={DashboardComponent}
/>
</div>
);
}
}
Notice that the to prop's value is the same as the value assigned to the path prop in <Route>. The page now renders two links:
When you click on Home, you will see the text Inside Home route displayed, and, when you click on Dashboard, you will be navigated to the route with its path prop set to /dashboard.
When you navigate to a route using <Link>, history.push() is called, which adds an entry to the history stack. Thus, when you click the browser's back button, you will be navigated to the previous route that you were accessing (the Home route). As mentioned in the previous chapter, the history library is used by React-Router to maintain the state of the application as the user traverses through various routes during the application journey.
The <Link> component has two other props—replace and innerRef.
The replace prop
The replace prop in <Link> calls history.replace(), which replaces the current entry in the history stack with the new path name mentioned in the to prop:
<Linkto="/dashboard" replace>Dashboard</Link>
For example, if you access the page at the path /home, accessing the preceding link will replace the current entry in the history stack with /dashboard, which basically replaces the entry /home with /dashboard.
The innerRef prop
React provides ref to get a reference to the rendered DOM element. This reference (ref) can then be used to perform certain operations outside the regular flow, such as focusing on the input element, media playback, and so on. <Link> is a composite component and it renders an anchor element on the DOM.
The <Link> component mentioned in the previous code snippet translates to anchor elements as follows:
..
<nav>
<a href="/">Home</a>
<a href="/dashboard">Dashboard</a>
</nav>
..
To get a reference to this rendered anchor element, the prop innerRef is added to <Link>:
<nav>
<Link
to="/"
innerRef={this.refCallback}>
Home
</Link>
<Link
to="/dashboard"
innerRef={this.refCallback}>
Dashboard
</Link>
</nav>
The innerRef prop accepts a callback function as its value; here, a function refCallback is specified as a value to the innerRef prop. The refCallback gets the reference to the inner element of the <Link> component:
refCallback(node) {
node.onmouseover= () => {
node.focus();
}
}
The callback function—refCallback—is called when the <Link> component mounts. From the preceding code snippet, we can see that a mouseover handler is added for both the anchor elements rendered by the two <Link> components. When the user hovers over the link, the corresponding anchor gets a focus.
The to prop with an object
The to prop can be either a string or an object. The object can contain the following properties:
• pathname: The path to navigate to
• search: The query parameters to the path, represented as a string value
• hash: a hash string to add to the URL
• state: an object containing state information that the rendered component can consume
Using these parameters, let's add a <Link> component:
<Link
to={{
pathname:'/user',
search:'?id=1',
hash:'#hash',
state: { isAdmin:true }
}}>
User
</Link>
The preceding code translates to the following:
<a href="/user?id=1#hash">User</a>
The state information is not included in the URL path; however, it's available to the component that gets rendered as a result of a <Route> match:
<Route
path="/user"
render={({ location }) => {
const { pathname, search, hash, state } = location;
return (
<div>
Inside User route
<h5>Pathname: {pathname}</h5>
<h5>Search: {search}</h5>
<h5>Hash: {hash}</h5>
<h5>State: {'{'}
{Object.keys(state).map((element, index) => {
return (
<spankey={index}>
{element}: {state[element].toString()}
</span>
)
})}
{'}'}
</h5>
</div>
);
}}
/>
The location object contains all of the previously defined parameters, including the state object.
The state object can be used to store data as the user navigates through the application and provide this data to the component that gets rendered next as a result of <Route> match.
The NavLink component
The <NavLink> component is similar to the <Link> component, except that several props can be specified that help you to conditionally add styling attributes to the rendered element. It accepts the same set of props as the <Link> component (to, replace, and innerRef) for navigating to a route, and it includes props to style the selected route.
Let's take a look at these props that help you style the <NavLink> component.
The activeClassName prop
By default, the class nameactive is applied to the active<NavLink>component. For example, when a<NavLink>is clicked and the corresponding route is rendered, the selected<NavLink>has its class name set toactive. To change this class name, specify the activeClassName prop on the <NavLink> component with its value set as the CSS class name that you want to apply:
<nav>
<NavLink to="/">Home</NavLink>
<NavLink
to="/dashboard"
activeClassName="selectedLink">
Dashboard
</NavLink>
</nav>
The next step is to specify the styles for the CSS class selectedLink in your application's CSS file. Note that the first <NavLink> does not specify the activeClassName prop. In this case, when the <NavLink> is clicked, the active class is added:
<nav>
<a class="active" aria-current="page" href="/">Home</a>
<a aria-current="page" href="/dashboard">Dashboard</a>
</nav>
However, when the second <NavLink> is clicked, the selectedLink class is applied:
<nav>
<a aria-current="page" href="/">Home</a>
<a class="selectedLink" aria-current="page" href="/dashboard">Dashboard</a>
</nav>
The activeStyle prop
The activeStyle prop is also used to style the selected <NavLink>. However, instead of providing a class to apply when the <NavLink> is selected, the CSS style properties can be provided inline:
<NavLink
to="/user"
activeStyle={{
background:'red',
color:'white'
}}>
User
</NavLink>
The exact prop
When you click on the <NavLink> with the to prop /dashboard, the active class (or inline style specified in activeStyle prop) is applied to both the <NavLink> components in the page. Similar to the <Route> component, the / in /dashboard matches the path specified in the to prop, and thus the active class is applied to both the <NavLink> components.
In this case, the exact prop can be used to apply the active class or activeStyle only when the path matches the browser's URL:
<NavLink
to="/"
exact>
Home
</NavLink>
<NavLink
to="/dashboard"
activeClassName="selectedLink">
Dashboard
</NavLink>
The strict prop
The <NavLink> component also supports the strict prop, which can be used to match the trailing slash specified in the to prop:
<NavLink
to="/dashboard/"
activeClassName="selectedLink"
strict>
Dashboard
</NavLink>
Here, the class selectedLink is applied to the <NavLink> component only when the browser's URL path matches the path /dashboard/—for example, when a trailing slash is present in the URL.
The isActive prop
The isActive prop is used to determine whether the <NavLink> component should have the active class applied (or inline styles specified in activeStyle prop). The function specified as a value to the isActive prop should return a Boolean value:
<NavLink
to={{
pathname:'/user',
search:'?id=1',
hash:'#hash',
state: { isAdmin:true }
}}
activeStyle={{
background:'red',
color:'white'
}}
isActive={(match, location) => {
if (!match) {
returnfalse;
}
constsearchParams = newURLSearchParams(location.search);
returnmatch.isExact && searchParams.has('id');
}}>
User
</NavLink>
From the preceding example, the function accepts two parameters—match and location. The styles defined in the activeStyle prop are applied only when the condition match.isExact && searchParams.has('id') evaluates to true, so, only when the match is exact and the URL has a query parameter id.
When the browser's URL is /user, the corresponding route defined with <Route> is displayed. However, the <NavLink> component will have the default styling and not the styles mentioned in the activeStyle prop, since the query parameter id is missing.
The location prop
The isActive function in <NavLink> receives the browser's history location and determines whether the browser's location.pathname matches the given condition. To provide a different location, include the location prop:
<NavLink
to="/user"
activeStyle={{
background:'red',
color:'white'
}}
location={{
search:'?id=2',
}}
isActive={(match, location) => {
if (!match) {
returnfalse;
}
constsearchParams = newURLSearchParams(location.search);
returnmatch.isExact && searchParams.has('id');
}}>
User
</NavLink>
Notice that the to prop doesn't specify the search parameter; however, the location prop includes it and, thus, when the browser's location is /user, the isActive function returns true, since the search parameter includes the id property.
If you found this article helpful, you can explore React Router Quick Start Guide. Filled with numerous hands-on examples, React Router Quick Start Guide helps you learn how to create and configure routes using different React Router components.