What's new in React Router v6?

Cover Image for What's new in React Router v6?

Hey everyone!

As you already know that React Router v6 is in BETA now. So, in this blog, we will be covering new features/changes in React Router v6.

What is React Router?

React Router is a standard library for routing in React. It allows you to handle routes in a web app, using dynamic routing. It enables us to navigate between various components in a React Application without the page refreshing when the user navigates.

Changes in React Router v6?

<Switch> is now <Routes>

Simply replace your <Switch> with <Routes> and you are good to go.

Tada

// React Router v5
import { BrowserRouter, Switch, Route } from 'react-router-dom';

function App() {
  return (
    <BrowserRouter>
      <Switch>
        <Route exact path="/"><Home /></Route>
        <Route path="/categories"><Categories /></Route>
      </Switch>
    </BrowserRouter>
  );
}
// React Router v6
import { BrowserRouter, Routes, Route } from 'react-router-dom';

function App() {
  return (
    <BrowserRouter>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/categories" element={<Categories />} />
      </Routes>
    </BrowserRouter>
  );
}

Simpler nested routes and layouts

<Routes> in React router v6 makes it really easy to define nested routes and relative routes making complex routes and layouts easier.

<Route> and <Link> values under v6's <Routes> element are automatically relative to the parent route that rendered them.

In React router v5, nested routes had to be defined and a lot of logic and path matching had to be done.

// React Router v5
import { BrowserRouter, Switch, Route, Link, useRouteMatch } from 'react-router-dom';

function App() {
  return (
    <BrowserRouter>
      <Switch>
        <Route exact path="/"><Home /></Route>
        <Route path="/categories"><Categories /></Route>
      </Switch>
    </BrowserRouter>
  );
}

function Categories() {
  const { match, url } = useRouteMatch();

  return (
    <div>
      <nav>
        <Link to={`${url}/shoes`}>Shoes</Link>
      </nav>

      <Switch>
        <Route path={`${path}/shoes`}>
          <Shoes />
        </Route>
        <Route path={`${path}/clothes`}>
          <Clothes />
        </Route>
      </Switch>
    </div>
  );
}

In React router v6, we can combine all our children routes and define them under the parent route in App

// React Router v6
import { BrowserRouter, Routes, Route, Link, Outlet } from 'react-router-dom';

function App() {
  return (
    <BrowserRouter>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="categories" element={<Categories />}>
          <Route path="shoes" element={<Shoes />} />
          <Route path="clothes" element={<Clothes />} />
        </Route>
      </Routes>
    </BrowserRouter>
  );
}

function Categories() {
  return (
    <div>
      <nav>
        <Link to="shoes">Shoes</Link>
      </nav>

      <Outlet />
    </div>
  );
}

Note: the <Outlet> component is used like {this.props.children} in React Router v6.

In the above example, <Outlet> is used to render child routes in Categories component. It will render either <Shoes> or <Clothes> depending on the location.

Object based routes

React router v6 ships with a new API for routing that uses plain JavaScript objects to declare routes.

The useRoutes hook lets us declare our routes using JavaScript objects instead of React elements.

Let's rewrite the above example with useRoutes hook.

import { BrowserRouter, Link, Outlet, useRoutes } from 'react-router-dom';

function App() {
  let element = useRoutes([
    { path: '/', element: <Home /> },
    {
      path: 'categories',
      element: <Categories />,
      children: [
        { path: 'shoes', element: <Shoes /> },
        { path: 'clothes', element: <Clothes /> },
      ]
    }
  ]);

  return element;
}

function Categories() {
  return (
    <div>
      <nav>
        <Link to="shoes">Shoes</Link>
      </nav>

      <Outlet />
    </div>
  );
}

Suspense ready navigation

The old useHistory hook has been removed and replaced by an all-new useNavigate hook.

useNavigate hook can be used to programmatically navigate in your application.

For example, after clicking on the profile button, you want the user to be redirected to the profile page.

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

function Home() {
  const history = useHistory();

  function clickHandler() {
    history.push('/profile');
  };

  return <button onClick={clickHandler}>My Profile</button>;
};
// React router v6
import { useNavigate } from 'react-router-dom';

function Home() {
  const navigate = useNavigate();

  function clickHandler() {
    navigate('/profile');
  };

  return <button onClick={clickHandler}>My Profile</button>;
};

Note: If you want to replace the URL in browser history instead of pushing, use { replace: true }

Smaller bundle size

Another significant change is the smaller bundle size. A comparison of the bundles for react-router-dom@5.2.0 vs. react-router-dom@6.0.0-beta.0 reveals the total bundle size decreased by 70%.

Smaller bundles mean your app loads more quickly, especially over slow/poor network connections.

react router.png


Thank you for reading this blog. Please feel free to provide any feedback or suggestions in the comments below. If you liked the blog and found it useful, do share it. 😀