score:133
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.
score:-4
import { BrowserRouter as Router, Routes, Route, Link } from "react-router-dom";
function App() {
return (
<Router>
<Routes>
<Route path="/" element={<h1>home page</h1>} />
<Route path="/seacrch" element={<h1>seacrch page</h1>} />
</Routes>
</Router>
);
}
export default App;
score:-1
for the Error "[Navigate] is not a component. All component children of must be a or <React.Fragment>"
use the following method maybe solved:
DefaultPage is when no match router, jump to the DefaultPage here use the <Route index element={} /> to replace the
<Navigate to={window.location.pathname + '/kanban'}/>
here is the link: https://reactrouter.com/docs/en/v6/getting-started/tutorial#index-routes
}/> }/> {/**/} } />score:0
For longer elements
<Router>
<div>
<Navbar totalItems={cart.total_items}/>
<Routes>
<Route exact path='/'>
<Route exact path='/' element={<Products products={products} onAddToCart={handleAddToCart}/>}/>
</Route>
<Route exact path='/cart'>
<Route exact path='/cart' element={<Cart cart={cart}/>}/>
</Route>
</Routes>
</div>
</Router>
score:0
Header will stay on all page
import React from 'react';
import {
BrowserRouter,
Routes,
Route
} from "react-router-dom";
const Header = () => <h2>Header</h2>
const Dashboard = () => <h2>Dashboard</h2>
const SurveyNew = () => <h2>SurveyNew</h2>
const Landing = () => <h2>Landing</h2>
const App = () =>{
return (
<div>
<BrowserRouter>
<Header />
<Routes >
<Route exact path="/" element={<Landing />} />
<Route path="/surveys" element={<Dashboard />} />
<Route path="/surveys/new" element={<SurveyNew/>} />
</Routes>
</BrowserRouter>
</div>
);
};
export default App;
score:0
you can use function for private route
<Route exact path="/login" element={NotAuth(Login)} />
<Route exact path="/Register" element={NotAuth(Register)} />
function NotAuth(Component) {
if (isAuth) return <Navigate to="/" />;
return <Component />;
}
score:0
Remove the PrivateRoute component from your project and use the following code in your App.js files:
import {Navigate} from "react-router-dom";
import {isauth} from 'auth'
...
<Route exact path="/home" element={<Home/>}/>
<Route exact path="/" element={isauth ? <Dashboard/> : <Navigate to="/Home" />}/>
score:1
If you are using a second file to work on your index.js . Here is a more simple code snippet that may help others understand better. It is pretty straight forward and you do not require "exact" and "switch" to change between the paths thanks to the new version.
index.js
import React from "react";
import ReactDOM from "react-dom";
import { BrowserRouter } from "react-router-dom";
import "./index.css";
import App from "./App";
ReactDOM.render(
<BrowserRouter>
<App />
</BrowserRouter>,
document.getElementById("root")
);
App.js
Note that you need to import { Routes, Route } instead of { Route } (as it was in previous versions). Also, note that on the App.js file, it is not necessary to import BrowserRouter again.
import { Routes, Route } from "react-router-dom";
import AllPages from "./pages/AllPages";
import NewContactsPage from "./pages/ContactsPage";
import FavoritesPage from "./pages/Favorites";
function App() {
return (
<div>
<Routes>
<Route path="/" element={<AllPages />} />
<Route path="/new-contacts" element={<NewContactsPage />} />
<Route path="/favorites" element={<FavoritesPage />} />
</Routes>
</div>
);
}
export default App;
score:1
This is the simple way to create private route
import React from 'react'
import { Navigate } from 'react-router-dom'
import { useAuth } from '../../context/AuthContext'
export default function PrivateRoute({ children }) {
const { currentUser } = useAuth()
if (!currentUser) {
return <Navigate to='/login' />
}
return children;
}
Now if we want to add private route to Dashboard component we can apply this private route as below
<Routes>
<Route exact path="/" element={<PrivateRoute><Dashboard /></PrivateRoute>} />
</Routes>
score:2
I tried all answers but it always display the error:
Error: [PrivateRoute] is not a component. All component children of must be a or <React.Fragment>
But i found a solution )))
In PrivateRoute.js file:
import React from "react"; import { Navigate } from "react-router-dom";
import {isauth} from 'auth'
const PrivateRoute= ({ children }) => {
const authed = isauth()
return authed ? children : <Navigate to={"/Home" /> };
export default ProtectedRoute;
In route.js file:
<Route
path="/"
element={
<ProtectedRoute >
<Dashboard/>
</ProtectedRoute>
}
/>
<Route exact path="/home" element={<Home/>}/>
score:3
React Router v6, some syntactic sugar:
{auth && (
privateRoutes.map(route =>
<Route
path={route.path}
key={route.path}
element={auth.isAuthenticated ? <route.component /> : <Navigate to={ROUTE_WELCOME_PAGE} replace />}
/>
)
)}
score:7
I know that this is not exactly the recipe how to make PirvateRoute
work, but just wanted to mention that new docs recommend a slightly different approach to handle this pattern with react-router v6:
<Route path="/protected" element={<RequireAuth><ProtectedPage /></RequireAuth>} />
import { Navigate, useLocation } from "react-router";
export const RequireAuth: React.FC<{ children: JSX.Element }> = ({ children }) => {
let auth = useAuth();
let location = useLocation();
if (!auth.user) {
return <Navigate to="/login" state={{ from: location }} />;
}
return children;
};
and you are supposed to add more routes inside ProtectedPage
itself if you need it.
See docs and example for more details. Also, check this note by Michael Jackson that goes into some implementation details.
score:7
Just set your router component to element prop:
<Routes>
<Route exact path="/" element={<Home />} />
<Route path="/about" element={<About />} />
<Route path="/dashboard" element={<Dashboard />} />
</Routes>
You can also check for upgrading from v5, https://reactrouter.com/docs/en/v6/upgrading/v5
score:17
Complement to reduce lines of code, make it more readable and beautiful.
This could just be a comment but I don't have enough points, so I'll put it as an answer.
Dallin's answer works but Drew's answer is better! And just to complete Drew's answer on aesthetics, I recommend creating a private component that takes components as props instead of children.
Very basic example of private routes file/component:
import { Navigate } from 'react-router-dom';
const Private = (Component) => {
const auth = false; //your logic
return auth ? <Component /> : <Navigate to="/login" />
}
Route file example:
<Routes>
<Route path="/home" element={<Home />} />
<Route path="/user" element={<Private Component={User} />} />
</Routes>
score:43
Only Route
components can be a child of Routes
. If you follow the v6 docs then you'll see the authentication pattern is to use a wrapper component to handle the authentication check and redirect.
function RequireAuth({ children }: { children: JSX.Element }) { let auth = useAuth(); let location = useLocation(); if (!auth.user) { // Redirect them to the /login page, but save the current location they were // trying to go to when they were redirected. This allows us to send them // along to that page after they login, which is a nicer user experience // than dropping them off on the home page. return <Navigate to="/login" state={{ from: location }} />; } return children; } ... <Route path="/protected" element={ <RequireAuth> <ProtectedPage /> </RequireAuth> } />
The old v5 pattern of create custom Route
components no longer works. An updated v6 pattern using your code/logic could look as follows:
const PrivateRoute = ({ children }) => {
const authed = isauth() // isauth() returns true or false based on localStorage
return authed ? children : <Navigate to="/Home" />;
}
And to use
<Route
path="/dashboard"
element={
<PrivateRoute>
<Dashboard />
</PrivateRoute>
}
/>
Source: stackoverflow.com
Related Query
- Error: [SystemFileRoutes] is not a Route component. All component children of Routes must be a Route or React.Fragment (React router V6)
- I am getting this error in react Error: [News] 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>
- Error: [Home] is not a <Route> component. All component children of <Routes> must be a <Route> or <React.Fragment>
- Navigate is not a <Route> component. All component children of <Routes> must be a <Route> or <React.Fragment>
- ReactJS: [Home] is not a <Route> component. All component children of <Routes> must be a <Route> or <React.Fragment>
- Error: [ProxyFacade] is not a <Route> component. All component children of <Routes> must be a <Route> or <React.Fragment>
- runtime.js:7 Uncaught Error: [RequireAuth] is not a <Route> component. All component children of <Routes> must be a <Route> or <React.Fragment>
- React js Error: Uncaught Error: [BrowserRouter] is not a <Route> component. All component children of <Routes> must be a <Route> or <React.Fragment>
- Error: [div] is not a <Route> component. All component children of <Routes> must be a <Route> or <React.Fragment>
- Layout is not a <Route> component. All component children of <Routes> must be a <Route> or <React.Fragment>. How should I overcome this error?
- RouteMapper is not a <Route> component. All component children of <Routes> must be a <Route> or <React.Fragment>
- Reactjs protected routes [Guard] is not a <Route> component. All component children of <Routes> must be a <Route> or <React.Fragment>
- Error: [AdminRoute] is not a <Route> component. All component children of <Routes> must be a <Route> or <React.Fragment>
- Uncaught Error: [RouteWrapper] is not a <Route> component. All component children of <Routes> must be a <Route> or <React.Fragment>
- Error: [undefined] is not a <Route> component. All component children of <Routes> must be a <Route> or <React.Fragment>
- Route does not render component on 2nd level of children
- Uncaught Error: [Topbar] is not a <Route> component. All component children of <Routes> must be a <Route> or <React.Fragment>
- How do I solve this error"Uncaught Error: [News] is not a <Route> component. All component children of <Routes> must be a <Route>or <React.Fragment>"?
- Uncaught Error: [PrivateRoute] is not a <Route> component. All component children of <Routes> must be a <Route> or <React.Fragment>
- Error: [News] is not a <Route> component. All component children of <Routes> must be a <Route> or <React.Fragment>
- Component does not remount when route parameters change
- React Route Component handle all "/" routes EXCEPT for "/login"
- TS2322 Error when extending Button, component property not found. What is the correct way to type?
- How to fix React Router component not updating as route changes
- Typescript error "Property does not exist on type 'JSX.IntrinsicElements'" when using native web component
- React Component not showing on matched Route (react-router-dom)
- Jest enzyme shallow test is not rendering all elements of the React component
- Creating reusable Button Component with React and Typescript with not assignable type error
- React router 4 `Link` component only changing the url and not updating the route
More Query from same tag
- Using react-input-mask with formik and formik-antd
- How do Inherit from custom React Component without losing flow type information?
- Failed removeChild when changing state in React
- How can I get react-bootstrap Navbar Hamburger to work in this case
- How to change the logic for the last element while mapping an array
- Only render specific component in a big react project
- Non hubspot form popup not creating contacts
- React unmounts and remounts layout components using react-router
- Are there any drawbacks to passing a state setter to a helper function?
- Get data from async function and update state
- Custom components based on Material UI and React
- Static site generator that renders React to HTML directly (no React in output)?
- How to display different tooltip text while mapping over a list?
- Showing a Nav component on all routes
- Render object value filtered against another array
- How to read from redux persisted store (localstorage)
- How does this code work with reactJs
- How to aovid using tabIndex for OnKeyDown catch event in react?
- How to use a JS library which is already provided by an html designer in React component, the js library is nice-select.sj?
- Expected an assignment or function call and instead saw an expression no-unused-expressions- ReactJs
- Best practice when adding whitespace in JSX
- I cant add next js link to mui appbar
- Import image using this.props.src in React
- Loop to dispatch a reducer in Redux
- React Js / Active item on menu with state
- Trouble understanding axios error handling in react
- Need help declaring TypeScript interface in React
- How to only return last api request (ReactJS)
- React Hooks and Axios Image Upload with Multer
- How to pass props onClick from one component to another in React JS