Home > Software engineering >  Why unable to use protectRoute inside Router in react?
Why unable to use protectRoute inside Router in react?

Time:06-04

I have a react application in which users can access the homepage only after login/signup. I have used protectRoutes to implement this , however I m getting the following error inside Router component:

A <Route> is only ever to be used as the child of <Routes> element, never rendered directly. Please wrap your <Route> in a <Routes>.

The code for app.js file:

import {useState} from 'react'
import './App.css';
import {Routes,Route,Link} from 'react-router-dom'
import SignupPage from './Pages/SignupPage';
import LoginPage from './Pages/LoginPage';
import Homepage from './Pages/Homepage';
import PrivateRoute from "./Pages/PrivateRoute";
import {HashRouter as Router} from 'react-router-dom'
function App() {
  const [username,setUsername]=useState("");
  const [currentUser,setCurrentUser]=useState({});
  return (
    <Router>
    <div className="App">
     <Route path="/" exact element={<SignupPage></SignupPage>}/>
     <Route path="/signup" exact element={<SignupPage currentuser={currentUser} setcurrentuser={setCurrentUser} setusername={setUsername}></SignupPage>}/>
     <Route path="/login" exact element={<LoginPage></LoginPage>}/>
     <PrivateRoute path="/homepage" exact currentuser={currentUser} element={<Homepage user={currentUser} username={username} setusername={setUsername}></Homepage>}/>
    </div>
    </Router>

  );
}

export default App;

Whats the error here and how do I fix it?

CodePudding user response:

Issue

You are rendering Route components directly and are not wrapping them in a Routes component.

Solution

Refactor the PrivateRoute component to render an Outlet component instead of a Route and wrap the routes you want to protect.

Example:

import { Navigate, Outlet } from 'react-router-dom';

const PrivateRoute = ({ currentuser }) => {
  // auth business logic

  return isAuthenticated
    ? <Outlet />
    : <Navigate to="/login" replace />;
};

...

import { HashRouter as Router, Routes, Route, Link} from 'react-router-dom'

function App() {
  const [username,setUsername]=useState("");
  const [currentUser,setCurrentUser]=useState({});
  return (
    <Router>
      <div className="App">
        <Routes>
          ... unprotected routes ...
          <Route path="/" element={<SignupPage />} />
          <Route
            path="/signup"
            element={(
              <SignupPage
                currentuser={currentUser}
                setcurrentuser={setCurrentUser}
                setusername={setUsername}
              />
            )}
          />
          <Route path="/login" element={<LoginPage />} />
          ...

          <Route element={<PrivateRoute currentuser={currentUser} />}>
            ... protected routes ...
            <Route
              path="/homepage"
              element={(
                <Homepage
                  user={currentUser}
                  username={username}
                  setusername={setUsername}
                />
              )}
            />
            ...
          </Route>
        </Routes>
      </div>
    </Router>
  );
}
  • Related