Navigating Different Routes

The Link component

Once we’ve divided the application into different routes, we would also like to link between these URLs. While we could easily use regular HTML anchors such as <a href="...">...</a>, this is not recommended. Each time such an anchor is used, we trigger a “hard” page refresh in the browser. The page would be left completely and would be loaded again.

In practice, we would ask for an HTML document that would load CSS and the JavaScript containing our React application from the server again (unless it is in the browser cache). Doing this would mean that everything is re-initialized based on each new URL. Any state that previously might have been set globally would be reset.

Single-page applications should not follow this pattern, and any HTML, CSS, and JavaScript should only be loaded from the server once. The global state should be persisted once we navigate through the routes, and only those parts of the page that actually change should re-render.

To facilitate said behavior, React Router supports a Link component. We can import it from the react-router-dom package, which also comes with a to prop. The Link component roughly equates to the regular href attribute on an HTML anchor element. We can use it like this:

<Link to="/account">Account</Link>

React Router also uses an <a href /> attribute under the hood. However, any clicks to this page are being intercepted and sent to an internal function, which then deals with displaying new page content based on the new URL without triggering a complete refresh of the page.

Apart from the to prop, Link components can also be equipped with an innerRef property. This will be filled by createRef() or useRef(), which both create a reference that can be used by the component. Moreover, Link also supports a replace prop, which allows us to replace the current URL in the browser history instead of creating a new history entry. Be careful, though: we cannot access the previous route when pressing the back button in the browser if we choose to make use of the replace prop.

Any other props that are passed to the Link element will be passed down to the generated anchor element. The line <Link to="/" title="Homepage">Home</Link> generates the following markup:

<a href="/" title="Homepage">Home</a>

Special case: NavLink

A special form of the Link element is the NavLink element. Apart from the usual props that can also be received by the Link component, NavLinks can change based on their state. The NavLink element can access information relating to which page it’s currently linking to and whether that page is the same as the current page. If this is the case, we can alter its display using activeClassName and activeStyle.

A classic example of this type of behavior is the overall page navigation. The currently active route in the menu is highlighted in a different color than other routes:

<NavLink to="/" activeClassName="active">Home</NavLink>
<NavLink to="/account" activeClassName="active">Account</NavLink>
<NavLink to="/contacts" activeClassName="active">Contacts</NavLink>

Only the Link of the current page receives the activeClassName active. If we had navigated to the /account URL, the markup would resemble the following:

<a href="/">Home</a>
<a href="/account" class="active">Account</a>
<a href="/contacts">Kontakte</a>

The NavLink element can also receive an exact and strict prop (similar to the same props for the Route component) as well as an isActive prop. The latter expects a function which either returns true (if the current page is the same as the one provided in NavLink) or false (if the current page is not the same as NavLink). The function takes the previously mentioned match object as its first argument and a location object as its second, which are both passed in from the Router element. The function can then decide whether to mark the NavLink as active or not, based on the information available.

Get hands-on with 1200+ tech skills courses.