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
Communication Between Sibling Components in Vue.Js 2.0
Adding Custom Properties to a Function
How to Watch for a Route Change in Angularjs
How to Detect When the Mouse Leaves the Window
Dynamic Function Name in JavaScript
JavaScript Url Decode Function
How to Prevent Caching of My JavaScript File
How to Stop JavaScript Execution
How to Add Extra Info to Copied Web Text
How to Disable Text Selection Using Jquery
Should I Be Using Object Literals or Constructor Functions
Best Cross-Browser Method to Capture Ctrl+S with Jquery
Basic JavaScript Promise Implementation Attempt
JavaScript Variables Declare Outside or Inside Loop
How to Count Certain Elements in Array
ASP.NET Postback with JavaScript