Error: [Privateroute] Is Not a <Route> Component. All Component Children of <Routes> Must Be a <Route> or <React.Fragment>

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

I ran into the same issue today and came up with the following solution based on this very helpful article by Andrew Luca

In PrivateRoute.js:

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

const PrivateRoute = () => {
const auth = null; // determine if authorized, from context or however you're doing it

// If authorized, return an outlet that will render child elements
// If not, return element that will navigate to login page
return auth ? <Outlet /> : <Navigate to="/login" />;
}

In App.js (I've left in some other pages as examples):

import './App.css';
import React, {Fragment} from 'react';
import {BrowserRouter as Router, Route, Routes} from 'react-router-dom';
import Navbar from './components/layout/Navbar';
import Home from './components/pages/Home';
import Register from './components/auth/Register'
import Login from './components/auth/Login';
import PrivateRoute from './components/routing/PrivateRoute';

const App = () => {
return (
<Router>
<Fragment>
<Navbar/>
<Routes>
<Route exact path='/' element={<PrivateRoute/>}>
<Route exact path='/' element={<Home/>}/>
</Route>
<Route exact path='/register' element={<Register/>}/>
<Route exact path='/login' element={<Login/>}/>
</Routes>
</Fragment>
</Router>

);
}

In the above routing, this is the private route:

<Route exact path='/' element={<PrivateRoute/>}>
<Route exact path='/' element={<Home/>}/>
</Route>

If authorization is successful, the element will show. Otherwise, it will navigate to the login page.

ReactJS: [Home] is not a Route component. All component children of Routes must be a Route or React.Fragment

first of all check the version of Your react router Dom .This error appear when you have V6 of react-router-dom. V6 have many groundbreaking change so try to read official documentation
check this out:https://reacttraining.com/blog/react-router-v6-pre/
Now for your question part
React router v6 introduce Routes

Introducing Routes

One of the most exciting changes in v6 is the
powerful new element. This is a pretty significant upgrade
from v5's element with some important new features including
relative routing and linking, automatic route ranking, and nested
routes and layouts.

  <BrowserRouter>
<div className="App" style={{ backgroundImage: "url(./circle.jpg)" }}>
<Header />
<Routes>
<Route exact path="/" element={<Home/>} />
<Route path="/quiz" element={<Quiz/>} />

</Routes>
</div>
<Footer />
</BrowserRouter>

Also check migration guide from v5 to v6
https://github.com/ReactTraining/react-router/blob/f59ee5488bc343cf3c957b7e0cc395ef5eb572d2/docs/advanced-guides/migrating-5-to-6.md#relative-routes-and-links

Error: [undefined] is not a Route component. All component children of Routes must be a Route or React.Fragment

You should pass the component as "element", like:

<Route path="/" element={<Dashboard/>}>

Or for protected routes:

<Route
path="home"
element={
<ProtectedRoute user={user}>
<Home />
</ProtectedRoute>
}
/>
...
</Routes>

Error Uncaught Error: [App] is not a Route component. All component children of Routes must be a Route or React.Fragment

Just render App in the router, not a Routes component. Only Route and React.Fragment components are valid children of the Routes component.

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
<BrowserRouter>
<App />
</BrowserRouter>
);

Uncaught Error: [ProtectedRoute] is not a Route component. All component children of Routes must be a Route or React.Fragment

I think the Route component needs to be a direct child of routes but you could wrap the Profile component in a Protected component maybe?

Something like:

const Protected = ({ isAdmin, component: Component, ...routeProps }) => {
const { loading, isAuthenticated, user } = useSelector((state) => state.user);

if (!loading && isAuthenticated === false) {
return <Navigate to="/login" />;
}

if (!loading && isAdmin === true && user?.role !== "admin") {
return <Navigate to="/login" />;
}

return (
<Fragment>
{loading === false ? (
<Component {...routeProps} />
) : null}
</Fragment>
);
};

And then you should be able to use it like this:

<Routes>
<Route exact path='/' element={<Home/>} />
<Route exact path='/product/:id' element={<ProductDetails/>} />
<Route exact path='/products' element={<Products/>} />
<Route path='/products/:keyword' element={<Products/>} />
<Route exact path='/search' element={<Search/>} />
<Route exact path='/account' element={<Protected component={Profile} />} />
<Route exact path='/login' element={<LoginSignUp/>} />
</Routes>

That example assumes any props you pass into the Protected component would then get passed down to the child.

Alternatively you could just render the child component inside of Protected:

<Routes>
<Route exact path='/' element={<Home />} />
<Route exact path='/product/:id' element={<ProductDetails />} />
<Route exact path='/products' element={<Products />} />
<Route path='/products/:keyword' element={<Products />} />
<Route exact path='/search' element={<Search />} />
<Route
exact
path='/account'
element={
<Protected>
<Profile />
</Protected>
}
/>
<Route exact path='/login' element={<LoginSignUp />} />
</Routes>

In which case the Protected component would look something like this:

const Protected = ({ isAdmin, children }) => {
const { loading, isAuthenticated, user } = useSelector(state => state.user)

if (!loading && isAuthenticated === false) {
return <Navigate to='/login' />
}

if (!loading && isAdmin === true && user.role !== 'admin') {
return <Navigate to='/login' />
}

return <Fragment>{loading === false ? children : null}</Fragment>
}

Honestly though, there's really quite a few ways to handle authenticated routing architecture.

Uncaught Error: [Elements] is not a Route component. All component children of Routes must be a Route or React.Fragment

Issue

This issue is that you are rendering something other than a Route or React.Fragment inside the Routes component.

{stripeApiKey && (
<Elements stripe={stripePromise}>
<Route path="/order/payment" element={<Payment />} />
</Elements>
)}

The Elements component is neither and fails the invariant check.

Solution

Refactor this into a layout route component similar to the ProtectedRoute component.

Example:

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

const StripeLayout = ({ stripeApiKey }) => {
return stripeApiKey
? <Outlet />
: <Navigate to="/" replace />
};

...

<Route element={<ProtectedRoute />}>
<Route path="/account" element={<Profile />} />
<Route path="/me/update" element={<ProfileEdit />} />
<Route path="/password/update" element={<UpdatePassword />} />
<Route path="/login/shipping" element={<Shipping />} />
<Route path="/order/confirm" element={<ConfirmOrder />} />
<Route element={<StripeLayout {...{ stripeApiKey }} />}>
<Route
path="/order/payment"
element={(
<Elements stripe={stripePromise}>
<Payment />
</Elements>
)}
/>
</Route>
</Route>

Error: [Home] is not a Route component. All component children of Routes must be a Route or React.Fragment

<Route path="/" element={<Home />} />

This change is necessary because react-router 6 reserves the child prop of <Route> for nesting routes.

Migrating to v6



Related Topics



Leave a reply



Submit