0

I'm trying to get the guard working, following the solution I found to this question:

Error: [PrivateRoute] is not a component. All component children of must be a or <React.Fragment>

But I get this error: A <Route> is only ever to be used as the child of <Routes> element, never rendered directly. Please wrap your <Route> in a <Routes>. Anyone know how to fix it?

Below is my code in App.js whitout imports:

//all imports

function PrivateRoute({ element, ...rest }) {
  const isAuthenticated = localStorage.getItem('token'); 
  return (
    <Route
      {...rest}
      element={isAuthenticated ? element : <Navigate to="/products" />} 
    />
  );
}

function App() {
  return (
    <div className="App">
      <header className="App-header">
        <Router>
          <Fragment>
            <MainTemplate />
            <Routes>
              <Route exact path='/' element={<Login />} />
              <Route exact path='/products' element={<PrivateRoute />}>
                <Route exact path='/products' element={<Products />} />
              </Route>
              <Route exact path='/product/:id' element={<PrivateRoute />}>
                <Route exact path='/product/:id' element={<Product />} />
              </Route>
              <Route exact path='/add-product' element={<PrivateRoute />}>
                <Route exact path='/add-product' element={<AddProduct />} />
              </Route>
              <Route exact path='/edit-product/:id' element={<PrivateRoute />}>
                <Route exact path='/edit-product/:id' element={<UpdateProduct />} />
              </Route>
              <Route exact path='/orders' element={<PrivateRoute />}>
                <Route exact path='/orders' element={<Orders />} />
              </Route>
              <Route exact path='/edit-order/:id' element={<PrivateRoute />}>
                <Route exact path='/edit-order/:id' element={<UpdateOrder />} />
              </Route>
              <Route exact path='/:category' element={<PrivateRoute />}>
                <Route exact path='/:category' element={<Category />} />
              </Route>
            </Routes>
          </Fragment>
        </Router>
      </header>
    </div>
  );
}

export default App;

Thanks to whoever will answer!

JDev
  • 25
  • 6
  • Does this answer your question? [Reactjs protected routes \[Guard\] is not a component. All component children of must be a or ](https://stackoverflow.com/questions/71471819/reactjs-protected-routes-guard-is-not-a-route-component-all-component-child) – Junaid Shaikh Mar 02 '23 at 10:52

3 Answers3

0

I think you should refactor your code into a simplified version and more readable. I checked the link you have provided at the top and inside that solution is the version he/she was referering to. Please find it below and I think it will help you fix the problem and simplify your code a little bit.

link (https://stackblitz.com/github/remix-run/react-router/tree/main/examples/auth?file=src%2FApp.tsx)

duro.codes
  • 26
  • 2
0

You need to remove nested Route components. If you want some path to be private, then just use your PrivateRoute realisation instead of native Route.

<Routes>
  <Route exact path='/' element={<Login />} />
  <PrivateRoute exact path='/products' element={<Products />} />
  <PrivateRoute exact path='/product/:id' element={<Product />} />
</Routes>

PrivateRoute should check if user has access to certain page, and if so return native Route with right component.

Basic PrivateRoute component

const PrivateRoute = (props) => {
  const user = somehowGetUserInfo();
  
  if (!user.isLoggedIn) {
    return <div>This page is private, please log in</div>;
  }
  
  return <Route {...props} />
};
t1m0n
  • 3,413
  • 1
  • 17
  • 21
0

You are using the Route not properly. maybe following solutions would be helpful :

  1. You are declaring two components to be render when your website get loaded i.e as well as . You may enhance it by using

    <Route exact path='/login' element={} />
    <Route exact path='/' element={} />

  2. You may refactor your code and following youtube video may help you : https://www.youtube.com/watch?v=Ul3y1LXxzdU&t=184s

Asma
  • 103
  • 5