'How to redirect in React Router v6?

I am trying to upgrade to React Router v6 (react-router-dom 6.0.1).

Here is my updated code:

import { BrowserRouter, Navigate, Route, Routes } from 'react-router-dom';

<BrowserRouter>
  <Routes>
    <Route path="/" element={<Home />} />
    <Route path="/lab" element={<Lab />} />
    <Route render={() => <Navigate to="/" />} />
  </Routes>
</BrowserRouter>

The last Route is redirecting the rest of paths to /.

However, I got an error

TS2322: Type '{ render: () => Element; }' is not assignable to type 'IntrinsicAttributes & (PathRouteProps | LayoutRouteProps | IndexRouteProps)'.   Property 'render' does not exist on type 'IntrinsicAttributes & (PathRouteProps | LayoutRouteProps | IndexRouteProps)'.

However, based on the doc, it does have render for Route. How to use it correctly?



Solution 1:[1]

I think you should use the no match route approach.

Check this in the documentation.

https://reactrouter.com/docs/en/v6/getting-started/tutorial#adding-a-no-match-route

import { BrowserRouter, Navigate, Route, Routes } from 'react-router-dom';

<BrowserRouter>
  <Routes>
    <Route path="/" element={<Home />} />
    <Route path="/lab" element={<Lab />} />
    <Route
        path="*"
        element={<Navigate to="/" replace />}
    />
  </Routes>
</BrowserRouter>

Update - 18/03/2022

To keep the history clean, you should set replace prop. This will avoid extra redirects after the user click back. Thanks @Paul for this tip.

Solution 2:[2]

I found another way to do this:

import { useNavigate } from "react-router-dom";
let navigate = useNavigate();

useEffect(() => {
   if (LoggedIn){
      return navigate("/");
   }
},[LoggedIn]);

https://reactrouter.com/docs/en/v6/getting-started/overview#navigation

Solution 3:[3]

Create the file RequireAuth.tsx

import { useLocation, Navigate } from "react-router-dom";
import { useAuth } from "../hooks/Auth";

export function RequireAuth({ children }: { children: JSX.Element }) {
  let { user } = useAuth();
  let location = useLocation();

  if (!user) {
    return <Navigate to="/" state={{ from: location }} replace />;
  } else {
    return children;
  }
}

Import the component to need user a private router:

import { Routes as Switch, Route } from "react-router-dom";

import { RequireAuth } from "./RequireAuth";
import { SignIn } from "../pages/SignIn";
import { Dashboard } from "../pages/Dashboard";

export function Routes() {
  return (
    <Switch>
      <Route path="/" element={<SignIn />} />
      <Route
        path="/dashboard"
        element={
          <RequireAuth>
            <Dashboard />
          </RequireAuth>
        }
      />
    </Switch>
  );
}

Solution 4:[4]

import { useState } from "react"
import { Navigate } from "react-router-dom"
const [login, setLogin] = useState(true)
return (<>
{!login && <Navigate to="/login" />}
<>)

Solution 5:[5]

In V5 of react ie. react-router-dom we had Redirect component. But in V6 of react it is updated to Navigate components.

We can pass replace in this components to avoid unnecessary redirects on clicking back and forward option.

Demonstration for usage is attached below :

<Route  path="/" element={user ? <Home /> : <Register />} />
<Route path="/login" element={user ? <Navigate to="/" replace /> :  <Login />}  />
<Route path = "/register" element={user ? <Navigate to="/" replace /> :  <Register />} />

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Hamedo Esk
Solution 3 AbĂ­lio Soares Coelho
Solution 4 Md Saif Uddin
Solution 5