reactjsreact-routerreact-router-domreact-router-component

React Routes does not recognize ProtectedRoute component as a Route


When adding a protected route in the component, it does not recognize it as a route. Here are the ProtectedRoute and App.js:

import React from 'react';
import { Route, Navigate } from 'react-router-dom';
import { useAuth } from './AuthContext';

const ProtectedRoute = ({ element: Element, ...rest }) => {
  const { user } = useAuth();

  return (
    <Route
      {...rest}
      element={user ? <Element /> : <Navigate to="/login" replace />}
    />
  );
};

export default ProtectedRoute;

import React from "react";
import { BrowserRouter as Router, Routes, Route, Navigate } from "react-router-dom";
import Header from './components/Header';
import Footer from './components/Footer';
import Home from './components/Home';
import About from './components/About';
import Dashboard from './components/Dashboard';
import Login from './components/Login';
import Register from './components/Register';
import ProtectedRoute from './components/ProtectedRoute';
import { AuthProvider } from './components/AuthContext';

function App() {
  return (
    <AuthProvider>
      <Router>
        <Header />
        <Routes>
          <Route path="/" element={<Home />} />
          <Route path="/about" element={<About />} />
          <Route path="/login" element={<Login />} />
          <Route path="/register" element={<Register />} />
          <ProtectedRoute path="/dashboard" element={<Dashboard />} />
        </Routes>
        <Footer />
      </Router>
    </AuthProvider>
  );
}

export default App;

Usually that could happen when the version of reat-router-dom is too old but in my case is above 6 which I reckon does the job.

I tried to delete all dependencies and install them again, no success. Also tried to add the logic of the component straight into the App component, didn't work. Another approach was to make the protected route receive only the component so that in App.js there would be only a Route with an element .


Solution

  • Nested routes should work:

    function Protected() {
      const { user } = useAuth()
    
      return user ? <Outlet /> : <Navigate to="/login" replace />
    }
    
    function App() {
      return (
        <AuthProvider>
          <Router>
            <Routes>
              <Route path="/" element={<Home />} />
              {/* ... */}
              <Route element={<Protected />}> {/* will only show up if one of the child routes matches */}
                <Route path="/dashboard" element={<Dashboard />} />
                {/* other protected routes */}
              </Route>
            </Routes>
          </Router>
        </AuthProvider>
      );
    }