Categories
React

Add Routing to a React App with Wouter

Spread the love

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.

By John Au-Yeung

Web developer specializing in React, Vue, and front end development.

Leave a Reply

Your email address will not be published. Required fields are marked *