Wouter is a library that lets us loading React components according to URLs.
In this article, we’ll look at how to add routing to a React app with Wouter.
Installation
To install it, we run:
npm i wouter
Getting Started
We can add routes to our React app by using the Route
component.
For instance, we can write:
import React from "react";
import { Link, Route } from "wouter";
const InboxPage = () => <p>inbox</p>;
export default function App() {
return (
<div>
<Link href="/users/1">
<a className="link">Profile</a>
</Link>
<Route path="/about">About Us</Route>
<Route path="/users/:name">
{(params) => <div>Hello, {params.name}!</div>}
</Route>
<Route path="/inbox" component={InboxPage} />
</div>
);
}
We add the Router
component to let us add map routes to React components.
:name
is a URL parameter.
We can get its value with params.name
.
Link
lets us create links to load routes.
We can also add the component
prop to add components as we did with InboxPage
.
useRoute Hook
We can use the useRouter
hook to extract URL parameters from a route.
For example, we write:
import React from "react";
import { Transition } from "react-transition-group";
import { useRoute } from "wouter";
export default function App() {
const [match, params] = useRoute("/users/:id");
return (
<div>
<Transition in={match}>
<p>Hi, this is: {params.id}</p>
</Transition>
</div>
);
}
We parse the route URL with tyhe useRoute
hook by passing it into the hook.
Then we get the params
object to get the URL parameters.
We also have the Transition
component to add transitions when we load routes.
useLocation Hook
We can use the useLocation
hook to return the location
object to get go to a different route.
For example, we write:
import React from "react";
import { Link, Route, useLocation } from "wouter";
const InboxPage = () => {
const [location, setLocation] = useLocation();
return (
<div>
<p>{`The current page is: ${location}`}</p>
<p>
<a onClick={() => setLocation("/about")}>Click to update</a>
</p>
</div>
);
};
export default function App() {
return (
<div>
<Link href="/inbox">
<a>Inbox</a>
</Link>
<Route path="/about">
<p>About Us</p>
</Route>
<Route path="/users/:name">
{(params) => <div>Hello, {params.name}!</div>}
</Route>
<Route path="/inbox" component={InboxPage} />
</div>
);
}
to add a link to the InboxPage
component.
The link uses the useLocation
hook’s setLocation
function to go to the about
route.
So when we click the Click to update link, we see About us.
Customizing the Location Hook
We can customize the useLocation
hook to do what we want.
For instance, we can extract URL segments from the hash instead of from URL parameters.
To do this, we write:
import React, { useCallback, useEffect, useState } from "react";
import { Link, Route, Router, useLocation } from "wouter";
const currentLocation = () => {
return window.location.hash.replace(/^#/, "") || "/";
};
const useHashLocation = () => {
const [loc, setLoc] = useState(currentLocation());
useEffect(() => {
const handler = () => setLoc(currentLocation());
window.addEventListener("hashchange", handler);
return () => window.removeEventListener("hashchange", handler);
}, []);
const navigate = useCallback((to) => (window.location.hash = to), []);
return [loc, navigate];
};
const InboxPage = () => {
const [location] = useLocation();
return (
<div>
<p>{`The current page is: ${location}`}</p>
</div>
);
};
export default function App() {
return (
<div>
<Link href="/inbox">
<a>Inbox</a>
</Link>
<Router hook={useHashLocation}>
<Route path="/about">
<p>About Us</p>
</Route>
<Route path="/users/:name">
{(params) => <div>Hello, {params.name}!</div>}
</Route>
<Route path="/inbox" component={InboxPage} />
</Router>
</div>
);
}
We have the currentLocation
function that gets the part of the URL after thw hash.
Then we pass that into the useState
hook to set the initial URL hash value.
And we listen for hashchange
events to get the changes to the hash part of the URL.
If there are any changes, we return the loc
location.
navigate
navigates to the hash part of the URL.
Then we pass the hook into the hook
prop to use it.
So now when we go to /#/users/1
, we see Hello, 1!
displayed.
When we go to /#/inbox
, we see The current page is: /inbox
And going to /#/about
renders About Us
.
Conclusion
Wouter is a lightweight router for React apps.