Navigation in React Router 6
Tags: react, javascript, webdev, tutorial
Published: 2021-12-24 05:58:33

> This was originally posted on [Saeloun's blog](https://blog.saeloun.com/2021/12/23/navigation-in-react-router-6).

While there are a lot of different libraries available for client-side routing, React Router is almost always the default choice.

## Why React Router?
As the user navigates, the browser keeps track of each location in a stack. That is how the back and forward buttons work.

For example, consider the user:

1. Clicks a link to `/blog`
2. Clicks a link to `/categories`
3. Clicks the back button
4. Clicks a link to `/contact`

The history stack will change as follows, where the **`highlighted`** entries denote the current URL.

1. **`/blog`**
1. `/blog`, **`/categories`**
1. **`/blog`**, `/categories`
1. `/blog`, **`/contact`**

If we click and hold the back button in a browser, we can see the browser’s history stack right there.

Now, some of us might argue that we don’t necessarily need a library to manipulate the history stack. We can do that programmatically like so:
```react
<a
  href="/blog"
  onClick={event => {
    // stop the browser from changing the URL
    event.preventDefault();
    // push an entry into the browser history stack and change the URL
    window.history.pushState({}, undefined, "/blog");
  }}
/>
```
While the above code changes the URL. It doesn’t do anything about the UI. We will still need to subscribe to the changes in the history stack to show the correct UI on `/blog`.

[Read more about browser’s History API](https://developer.mozilla.org/en-US/docs/Web/API/History).

React Router makes it easier for us to subscribe to the changes in the browser’s history stack. It also allows us to manipulate the history stack.

## Navigation

React Router provides us with an easy-to-use interface for navigation.

We can use:
1. `<Link>` and `<NavLink>`, which renders an `<a>` element. We can initiate navigation by clicking on it.
2. `useNavigate` and `<Navigate>` which enables us to navigate programmatically.

Let us look at `<Link>` and `<NavLink>` and their usage:
```react
import { Link } from "react-router-dom";

function Navbar() {
  return (
    <nav>
      <Link to="blog">Blog</Link>
      <Link to="categories">Categories</Link>
      <Link to="contact">Contact</Link>
    </nav>
  )
}
```

We can use `<NavLink>` in the above example instead of `<Link>`.

The difference between the two is that `<NavLink>` knows whether or not it is _"active"_. So if we want to apply some styles to the active link, we need to use `<NavLink>`.

[Read more about NavLink](https://reactrouter.com/docs/en/v6/api#navlink).

Now, consider a scenario where we want to navigate our users to `/dashboard` after they successfully log in. This is exactly the place where we would want to navigate programmatically.

React Router provides us `useNavigate` and `<Navigate>` to do exactly that.

Let us see how we can use them:

```react
import React, { useState } from "react";
import { useNavigate } from "react-router-dom";

function LoginForm() {
  const [user, setUser] = useState(null);
  const [error, setError] = userState(null);
  const navigate = useNavigate();

  const handleSubmit = event => {
    event.preventDefault();
    try {
      const user = await login(event.target);
      setUser(user);
      navigate("/dashboard", { replace: true });
    } catch (error) {
      setError(error);
    }
  }

  return (
    <div>
      {error && <p>{error.message}</p>}
      <form onSubmit={handleSubmit}>
        <input type="text" name="username" />
        <input type="password" name="password" />
        <button type="submit">Login</button>
      </form>
    </div>
  );
}
```
Alternatively, we can also use `<Navigate>` like this:

```react
import React, { useState } from "react";
import { Navigate } from "react-router-dom";

function LoginForm() {
  const [user, setUser] = useState(null);
  const [error, setError] = userState(null);

  const handleSubmit = event => {
    event.preventDefault();
    try {
      const user = await login(event.target);
      setUser(user);
    } catch (error) {
      setError(error);
    }
  }

  return (
    <div>
      {error && <p>{error.message}</p>}
      {user && (
        <Navigate to="/dashboard" replace={true} />
      )}
      <form onSubmit={handleSubmit}>
        <input type="text" name="username" />
        <input type="password" name="password" />
        <button type="submit">Login</button>
      </form>
    </div>
  );
}
```

With this, we do not have to worry about manipulating the history stack and subscribing to its changes. React Router handles all of that for us!

React Router 6 provides a few low-level APIs that can be useful while building our navigation interfaces -

- [useResolvedPath](https://reactrouter.com/docs/en/v6/api#useresolvedpath)
- [useHref](https://reactrouter.com/docs/en/v6/api#usehref)
- [useLocation](https://reactrouter.com/docs/en/v6/api#uselocation)
- [useLinkClickHandler](https://reactrouter.com/docs/en/v6/api#uselinkclickhandler)
- [useLinkPressHandler](https://reactrouter.com/docs/en/v6/api#uselinkpresshandler)
- [resolvePath](https://reactrouter.com/docs/en/v6/api#resolvepath)

Check out the [React Router 6 API doc to learn more](https://reactrouter.com/docs/en/v6/api#navigation).

> P.S. This is my first ever blog here. Your feedback is highly appreciated 🙏 😄