This tutorial is out of date and no longer maintained.
Reach Router is authored by Ryan Florence. If you recognize his name it’s because he’s the original co-author of React Router, which is currently the most popular routing library.
Both libraries appear to have identical purposes to provide a routing layer for the web. However, Reach Router is taking a fresh approach to the solution, and it also comes with accessibility (a11y) baked-in and working out of the box.
Warning: Since the original publication, it has been announced that React Router will adopt many of the features of Reach Router. You should consult the “Which Project Should I Choose Today?” section for your project’s needs.
In this article, you will compare React Router to Reach Router in order to better understand what each library supports and provides.
To follow along with this tutorial, you will need:
Reach Router is very similar to React Router and uses similar namespaces like <Router>
, <Link>
, etc., but there are some noteworthy differences. Let’s consider a basic setup for both react-router
and reach-router
.
First, a setup using React Router:
React Routerimport React from "react";
import { BrowserRouter as Router, Route } from "react-router-dom";
const App = () => {
return (
<Router>
<div>
<h1>Global Party Supplies, Inc</h1> // PATHS
<Route component={Home} path="/" exact/> // "/"
<Route component={About} path="/about"/> // "/about"
<Route component={Support} path="/support"/> // "/support"
<Route component={Dashboard} path="/dashboard"/> // "/dashboard"
<Route component={Invoices} path="/dashboard/invoices"/> // "/dashboard/invoices"
<Route component={Team} path="/dashboard/team"/> // "/dashboard/team"
<Route component={Report} path="/dashboard/:reportId"/> // "/dashboard/:reportId"
</div>
</Router>
);
}
React Router has its own <Route>
component that takes two props: component
and path
.
Here’s the same setup using Reach Router:
Reach Routerimport React from "react";
import { Router } from "@reach/router";
const App = () => {
return (
<div>
<h1>Global Party Supplies, Inc</h1>
<Router> // PATHS
<Home path="/"/> // "/"
<About path="about"/> // "/about"
<Support path="support"/> // "/support"
<Dashboard path="dashboard"> // "/dashboard"
<Report path=":reportId"/> // "/dashboard/:reportId"
<Invoices path="invoices"/> // "/dashboard/invoices"
<Team path="team"/> // "/dashboard/team"
</Dashboard>
</Router>
</div>
);
}
The first impression is that this looks really clean. Reach Router doesn’t have a <Route>
component. You just use the component itself (e.g., <Dashboard>
)! Using nested JSX for subpaths (/dashboard/team
) distinguishes itself from React Router.
But wait… there’s something weird here. At first glance you may think the <Report>
route would intercept /dashboard/invoices
and /dashboard/team
, but it actually doesn’t!
Reach Router uses a point system to rank your route definitions by looking at the path
value. When two paths seem to collide, params (:reportId
) and wildcard (*
) get low-priority, while explicit paths (invoices
and teams
) get higher priority. This means navigating to /dashboard/invoices
actually works, and /dashboard/example
goes to <Report>
.
Now that we’ve explored the basic setup, let’s explore how you would pass data to routes.
First, reportId
and salesData
with React Router:
React Router<Route
path="/dashboard/:reportId"
render={(props) => {
return <Report {...props} salesData={true} />
}}
/>
const Report = ({ props, match }) => {
return (
<h1>
{match.params.reportId} // "match" is from react-router
and
{props.salesData}
</h1>
)
}
There’s more stuff involved with React Router, but this is normal fare if you’ve been using it for any amount of time.
Here’s the same example with Reach Router:
Reach Router<Report
path="dashboard/:reportId" // static routes work too :)
salesData={this.state.salesData}
/>
const Report = (props) => {
return (
<h1>
{props.reportId}
and
{props.salesData}
</h1>
)
}
Note how reportId
does not require match
to access the URL parameters.
Next, let’s investigate how <Link>
ing works in both libraries.
Both Reach Router and React Router export a <Link>
component, but there are some differences. Let’s consider a <Dashboard>
component which has several subpages.
First, with React Router:
React Routerimport { Link } from "react-router-dom";
const Dashboard = ({ match, history }) => {
return (
<div>
<div>
<Link to={`${match.url}/invoices`}>Invoices</Link>
<Link to={`${match.url}/team`}>Team</Link>
</div>
<!-- content -->
<div>
<Link to="/">Home</Link>
<Link to="/about">About</Link>
<Link to="/support">Support</Link>
<a onClick={history.goBack}>Go Back</a>
</div>
</div>
);
}
With React Router you have to be specific with <Link>
which usually means you’ll have to use match.url
when you have subpaths beyond a root subpath (e.g., /host/path1/path2
). Also, note that you have to programmatically goBack
since there isn’t a utility for relative navigation.
Here’s the same example with Reach Router:
Reach Routerimport { Link } from "@reach/router";
const Dashboard = () => {
return (
<div>
<div>
<Link to="invoices">Invoices</Link>
<Link to="team">Team</Link>
</div>
<!-- content -->
<div>
<Link to="/">Home</Link>
<Link to="/about">About</Link>
<Link to="/support">Support</Link>
<Link to="../">Go Back</Link>
</div>
</div>
)
}
Reach Router supports relative links! It also fully supports Unix directory navigation like <a>
tags would.
In this article, you compared React Router to Reach Router in order to better understand what each library supports and provides.
Based on these comparisons, Reach Router is a very tempting alternative to React Router. Overall, it’s more elegant in conveying information when reading and writing the code. This shouldn’t come as a surprise as Ryan Florence is the co-author of react-router
, and most hard-fought insights can only be gotten through time and experience.
Give Reach Router a try! The first v1.0 release was in May 2018 and GatsbyJS v2 has already opted for Reach Router against React Router.
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!