React Icon Get 73% off the React Master bundle

See the bundle then add to cart and your discount is applied.

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)

In this post you’ll learn how to programmatically navigate with the latest React Router v6 with the new useNavigate hook.

To programmatically navigate means to use JavaScript, i.e. program code, a function or method call. If you just want to hyperlink then use <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.

With React Router setup and some example Hello and Goodbye components, let’s 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;

Now that navigate is readily available, we can call the function as many times as we like throughout the component and bind to various events, such as a click.

Check out the Stackblitz example below that 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 navigating!

Learn React the right way.

The most complete guide to learning React ever built.
Trusted by 82,951 students.

Todd Motto

with Todd Motto

Google Developer Expert icon Google Developer Expert

Related blogs 🚀

Free eBooks:

Angular Directives In-Depth eBook Cover

JavaScript Array Methods eBook Cover

NestJS Build a RESTful CRUD API eBook Cover