Search code examples
javascriptreactjsreact-routervite

Does the Navigate "to" support second level forwarding?


Here is my app.jsx

import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
import OTAndTOGateKeeper from "./components/otAndTO/OTAndTOGateKeeper.jsx";
import LoginForm from "./components/otAndTO/LoginForm.jsx";
 return (
    <Router>
      <Routes>
        <Route path='/otAndTO' element={<OTAndTOGateKeeper/>}>
          <Route index element={<OTAndTOForm/>}/>
          <Route path="login" element={<LoginForm/>}/>
        </Route>        
      </Routes>
    </Router>
);

Here is my OTAndTOGateKeeper.jsx

import { Navigate } from 'react-router-dom';
import OTAndTOForm from "./OTAndTOForm.jsx";
export default function OTAndTOGateKeeper(){
    let finalComponent;
    if (sessionStorage.getItem("accessToken")){
        finalComponent=<OTAndTOForm/>
    } else {
        finalComponent=<Navigate to="/otAndTO/login"/>
    }
    return finalComponent;
}

When I Browse the '/otAndTO', it should return the login form; unfortunately, there are nothing return.

However, when I change the App.jsx and OTAndTOGateKeeper.jsx as the following:

import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
import OTAndTOGateKeeper from "./components/otAndTO/OTAndTOGateKeeper.jsx";
import LoginForm from "./components/otAndTO/LoginForm.jsx";
 return (
    <Router>
      <Routes>
        <Route path='/otAndTO' element={<OTAndTOGateKeeper/>}>
          <Route index element={<OTAndTOForm/>}/>
        </Route>
        <Route path="login" element={<LoginForm/>}/>            
      </Routes>
    </Router>
);

import { Navigate } from 'react-router-dom';
import OTAndTOForm from "./OTAndTOForm.jsx";
export default function OTAndTOGateKeeper(){
    let finalComponent;
    if (sessionStorage.getItem("accessToken")){
        finalComponent=<OTAndTOForm/>
    } else {
        finalComponent=<Navigate to="/login"/>
    }
    return finalComponent;
}

It works as expected.

Here is my environment:

"react-dom": "^18.3.1",
"react": "^18.3.1",
"react-router-dom": "^7.0.2"

I am using the vite+react development tools.

Is the only work for the top level URL?


Solution

  • Does the Navigate "to" support second level forwarding?

    Yes, it will navigate to whatever path you specify.

    OTAndTOGateKeeper is a layout route component, so it must render an Outlet component for the nested routes to render their element content into. It also can't return a redirect to a route it is wrapping (because this replaces the Outlet and then nothing is rendered!).

    OTAndTOForm will be rendered on the /otAndTO index route, so OTAndTOGateKeeper should not also be trying to render it.

    Update OTAndTOGateKeeper to the following:

    import { Navigate, Outlet } from 'react-router-dom';
    import OTAndTOForm from "./OTAndTOForm.jsx";
    
    export default function OTAndTOGateKeeper() {
      return sessionStorage.getItem("accessToken")
        ? <Outlet />
        : <Navigate to="/otAndTO/login" replace />;
    }
    

    Rearrange the routes so that both the OTAndTOForm index route and the LoginForm login route are rendered under the parent "/otAndTO" route, and render OTAndTOGateKeeper as protected layout route only around the OTAndTOForm route.

    <Router>
      <Routes>
        <Route path="/otAndTO">
          <Route element={<OTAndTOGateKeeper />}>
            <Route index element={<OTAndTOForm />} />    {/* "/otAndTO" */}
          </Route>
          <Route path="login" element={<LoginForm />} /> {/* "/otAndTO/login" */}
        </Route>      
      </Routes>
    </Router>