ginoboy
ginoboy

Reputation: 83

How to use Protected Routes with react-router-dom V6 and typescript?

I am trying to implement a protected route to only allow logged in users to access my app. The code I have written seems to work, I am redirected to my login page when I try to access the homepage without being logged in, however once I am logged in I can access the page but I does not render and I get the following error: Click here for error

I have tried multiple methods and wrapping the element in my protected route seems like the V6 way of doing things, however it doesn't seem to work for me:

My protected route

interface PrivateRouteProps extends RouteProps {
}

const PrivateRoute: React.FC<PrivateRouteProps> = ({...rest}) => {
    const auth = useAuth();

    if (auth?.user === null) {
        return <Navigate to='/'/>;
    }
    return <Route {...rest}/>;
};

export default PrivateRoute;

My app (route usage)

function App() {
    useEffect(() => {
      API
        .get('api', '/reservation', {})
        .then(response => {
          console.log(response);
        })
        .catch(error => {
          console.log(error.response);
        });

    }, [])
    return (
      <Router>
        <Routes>
          <Route path='/' element={<LoginPage />}/>
          <Route path='/consultAndReserve' element={<PrivateRoute><Navbar/><ConsultReserve/></PrivateRoute>} />
          <Route path='/consultAndReserve/:date' element={<><Navbar/><ConsultReserveWithDate/></>}/>
          <Route path='/myReservations'  element={<><Navbar/><Reservations/></>}/>
          <Route path='/tracing'  element={<><Navbar/><Tracing/></>}/>
        </Routes>
      </Router>
  );
}

What am I doing wrong?

Upvotes: 7

Views: 9187

Answers (1)

Drew Reese
Drew Reese

Reputation: 202846

It's fairly trivial to create a "PrivateRoute" component, even in TypeScript.

In your case you can't directly render a Route component as the error points out. This was a breaking change between RRDv5 and RRDv6. You can render the children prop since you are directly wrapping the components you want to protect.

Example:

const PrivateWrapper = ({ children }: { children: JSX.Element }) => {
  const auth = useAuth();
  return auth?.user ? children : <Navigate to="/" replace />;
};

Usage:

<Routes>
  ...
  <Route
    path="/consoleAndReserve"
    element={(
      <PrivateWrapper>
        <Navbar />
        <ConsultReserve />
      </PrivateWrapper>
    )}
  />
  ...
</Routes>

Upvotes: 11

Related Questions