Introduction to React Router
React applications tend to be single page applications: You load one URL, the component hierarchy is rendered, and users manipulate this hierarchy through interactions with your app. If your application is more complex, you want to structure different functional parts into different routes. This is the task of React Router.
Essential Components
React Router introduces routing features with specific higher-order components:
Router
: The container that wraps your application, it needs to be placed as the first item in your container hierarchySwitch
: Contains severalRoute
definitions, the first match will be the first one that is renderedRoute
: Declares a path and optional params that are matched against the URLLink
: A wrapper that renders HTML anchor tags pointing to your defined routes
An important feature of using React Router is that any change to one of the specified routes leads to a re-render of the component tree, not a page refresh. Local application state persist between these re-renders.
Routing Rules in my Board Game App
The board game app consists of the following pages: Landing page, board game search, user search, user profile, my account, my collection and account login. Each page is accessible with a dedicated URL. Only the route for loading the user profile requires an additional parameter, the other pages determine required data according to application state.
Here is the declaration:
01 <Router>
02 <Nav />
03 <Route render={({ location }) => {
04 return (
05 <Switch >
06 <Route path="/bgsearch/" exact render={() => <BgSearch />} />
07 <Route path="/usersearch/" exact render={() => <UserSearch />} />
08 <Route path="/user/:id/" exact render={() => <UserProfile />} />
09 <Route path="/myaccount" exact render={() => <MyAccount />} />
10 <Route path="/mycollection" exact render={() => <MyCollection />} />
11 <Route path="/login" exact render={() => <AccountLogin />} />
12 <Route path="/" render={({ location }) => <HomePage />} />
13 </Switch>
14 );
15 }} />
16 <Footer />
17 </Router>
Lets explain these lines:
- Line 1: The
<Router>
component wraps all other react components - Line 3: The
<Route>
component wraps all route declarations - Line 5 - 13: Inside the
<Switch>
declaration, a choice will be made between the different<Route>
declaration. Each<Route>
contains three props: The path the URLs matches, the keywordexact
to only use exact matches, and finally therender()
method that returns JSX. As you see here, I always return the component that should be rendered.
The order of the <Route>
declaration is important! If I would put <Route path="/" ..>
at the beginning of this block, than all requests would go to this URL, because they all match the trailing /
. Therefore, use the keyword exact
in most route declaration, and put the remaining rules at the bottom.
Links in my Board Game App
Routes define the general URLs of your app. Now if inside your app you want to change to one of these pages, you need to use the special component <Link>
. This component interacts with the defined <Routes>
of your App and will not trigger a re-render, but re-render the component hierarchy.
Here is an example from the <Nav>
component of my board game app. Link declaration is very simple: Create a <Link>
component, with the prop to
, and put the link name as text inside this component.
01 import React from 'react';
02 import { Link } from 'react-router-dom';
03
04 function Nav() {
05 function render() {
06 return (
07 <nav className="flex-row">
08 <Link to="/">Home</Link>
09 <Link to="/bgsearch">Search Boardgame</Link>
10 <Link to="/usersearch">Search Users</Link>
11 <Link to="/myaccount">My Account</Link>
12 <Link to="/mycollection">My Collection</Link>
13 ...
14 </nav>
15 );
16 };
17 return render();
20 }
Conclusion
React Router is great tool to structure your React app into different pages. It is easily added to your existing app: You just define, at the top level of your app, all <Route>
of the app. Then, whenever you want to switch to a page, you are using a <Link>
component. With these changes, no more page refreshes occur, and the app state persists between changing to different pages.