Home > Enterprise >  React PrivateRoute auth route
React PrivateRoute auth route

Time:03-13

I am working on a basic react auth app, right now the routes /signup and /login work when I run this repo with my .env.local file that contains firebase auth variables. https://github.com/MartinBarker/react-auth-app

I am trying to make it so that the '/' route that points to Dashboard will only be accessible for a user who is currently signed in, and if a user is not signed in but tries to access the '/' route they will be redirected to the '/login' page.

But whenever I use the route

<PrivateRoute exact path="/" element={Dashboard} /> 

my chrome devtools console shows a blank page with error messages:

index.tsx:24 Uncaught Error: [PrivateRoute] is not a <Route> component. All component children of <Routes> must be a <Route> or <React.Fragment>

my PrivateRoute.js looks like this:

// This is used to determine if a user is authenticated and
// if they are allowed to visit the page they navigated to.

// If they are: they proceed to the page
// If not: they are redirected to the login page.
import React from 'react'
import { Navigate, Route } from 'react-router-dom'
import { useAuth } from '../Contexts/AuthContext'

const PrivateRoute = ({ component: Component, ...rest }) => {

  // Add your own authentication on the below line.
  //const isLoggedIn = AuthService.isLoggedIn()

  const { currentUser } = useAuth()
  console.log('PrivateRoute currentUser = ', currentUser)

  return (
    <Route
      {...rest}
      render={props =>
        currentUser ? (
          <Component {...props} />
        ) : (
          //redirect to /login if user is not signed in
          <Navigate to={{ pathname: '/login'}} />
        )
      }
    />
  )
}

export default PrivateRoute

Im not sure why this error is occurring, any help is appreciated

CodePudding user response:

This behaviour seems to have changed in ReactRouter V6 here is the solution we came up with for a project.

Private route *Re-creating the users question code

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

const PrivateRoute = ({ children }) => {

  // Add your own authentication on the below line.
  //const isLoggedIn = AuthService.isLoggedIn()

  const { currentUser } = useAuth()
  console.log('PrivateRoute currentUser = ', currentUser)

  return (
    <>
      {
      currentUser ? (
          children
        ) : (
          //redirect to /login if user is not signed in
          <Navigate to={{ pathname: '/login'}} />
        )
      }
    </>
  )
}

export default PrivateRoute

Typescript *Our actual code implementation of this issue

const PrivateRoute: React.FC = ({ children }) => {
  const navigate = useNavigate();
  const { isAuthenticated, isAuthLoading } = useAuth();
  const { user, isLoadingUser } = useContext(UserContext);

  // Handle users which are not authenticated
  // For example redirect users to different page

  // Show loader if token is still being retrieved
  if (isAuthLoading || isLoadingUser) {
    // TODO: show full page loader
    return (
      <div>Loading...</div>
    );
  }

  // Proceed with render if user is authenticated
  return (
    <>
      {children}
    </>
  );
};

Router

<Router>
  <Routes>
    <Route
      path={routes.user.accountSignup.path}
      element={
        <PrivateRoute>
          <AccountSignup />
        </PrivateRoute>
      }
    />
  </Routes>
</Router>
  • Related