💲 Black Friday Special

Get an extra 35% OFF everything with coupon code BLACK_FRIDAY

0 days
00 hours
00 mins
00 secs

Write React like a pro. React Icon

Follow the ultimate React roadmap.

Programmatically navigate with React Router (and Hooks)

How to programmatically navigate with React Router v6 and the new useNavigate hook.

To programmatically navigate means to use JavaScript, i.e. program code, a function or method call. If you just want a straight-up hyperlink then your best bet is <Link to="/some-url" />, otherwise here we go…

This post will answer questions like “How can I navigate on a click event in React?” or “What do I use to navigate to another URL inside a React component?”.

Assuming you’re working in the DOM, you’ll want to ensure you’ve installed npm install react-router-dom - I’m using React Router 6.4.3 and React 18.0.2.

Let’s get React Router setup, I’m importing components Hello and Goodbye to demonstrate how to handle navigating with hooks.

import * as React from 'react';
import { BrowserRouter as Router, Route, Routes } from 'react-router-dom';

import Hello from './Hello';
import Goodbye from './Goodbye';

const App = () => (
  <Router>
    <Routes>
      <Route exact path="/" element={<Hello />} />
      <Route path="/goodbye" element={<Goodbye />} />
    </Routes>
  </Router>
);

export default App;

React Router “useNavigate” hook

Introduced in React Router 6.0.0, the useNavigate hook is considered the new and future-facing direction for routing in React. It has a dependency on Remix Router and the core React Router.

Inside our Hello component, we’ll import the useNavigate hook from React Router and call it at the top of the functional component.

Then, create a handler like handleClick and assign it via an onClick handler:

import * as React from 'react';
import { useNavigate } from 'react-router-dom';

const Hello = () => {
  const navigate = useNavigate();
  const handleClick = () => navigate('/goodbye');

  return (
    <button type="button" onClick={handleClick}>
      Goodbye
    </button>
  );
};

export default Hello;

Clean, right? Now that navigate is readily available, we can call the function as many times as we like.

Check out the Stackblitz example below which demonstrates this new hooks approach:

What else does this new useNavigate hook give us then? Deltas.

Delta? That’s essentially a number, much like the traditional history API to navigate back and forth using the go() method.

To go back, like the browser’s “Back” button, simply pass -1:

const GoBack = () => {
  const navigate = useNavigate();
  const handleClick = () => navigate(-1);

  return (
    <button type="button" onClick={handleClick}>
      Go Back 
    </button>
  );
};

To go forward, like the browser’s “Forward” button, simply pass 1:

const GoForward = () => {
  const navigate = useNavigate();
  const handleClick = () => navigate(1);

  return (
    <button type="button" onClick={handleClick}>
      Go Forward 
    </button>
  );
};

This behavior is perfect for when dealing with dynamic URLs where you might not have the previous router state available, so it keeps things light and dynamic.

Bonus: TypeScript Interface

This is why I also like TypeScript, because even if you aren’t using it - it’s a clear descriptor of the API. Why am I telling you this? Because here’s the TypeScript interface:

declare function useNavigate(): NavigateFunction;

interface NavigateFunction {
  (
    to: To,
    options?: {
      replace?: boolean;
      state?: any;
      relative?: RelativeRoutingType;
    }
  ): void;
  (delta: number): void;
}

This tells us that we can also pass a second argument into navigate() which is an object of options. For example, replace will (as the name suggests) replace the current routing state in the history instead of creating a new item in the stack - and state for any state you wish to pass to another router.

Legacy: React Router v5 and useHistory

Before the useNavigate hook, version 5.0.0 of React Router shipped with a very similar method called useHistory. Here’s how that looked if you’re after version 5:

import React from 'react';
import { useHistory } from 'react-router-dom';

const Hello = () => {
  const history = useHistory();
  const handleClick = () => history.push('/goodbye');

  return (
    <button type="button" onClick={handleClick}>
      Goodbye
    </button>
  );
};

export default Hello;

Even though the API is very similar, the useNavigate hook is a nice improvement over the traditional-looking history API that the useHistory hook exposed.

Summary

We’ve covered a lot of ground here for something so simple, but I feel we’ve effectively explored our options. To recap:

Enjoyed the post? There’s lots more in my expert React courses where you’ll learn everything you need to know to be extremely good and proficient at React and the surrounding ecosystem, hooks and beyond!

Happy routing!

Related blogs 🚀

Free eBooks:

Angular Directives In-Depth eBook Cover

JavaScript Array Methods eBook Cover

NestJS Build a RESTful CRUD API eBook Cover