Reputation: 1446
I have routes with single and multiple components.I am using authguard to restrict access to some routes.How can I apply the authguard to the routes having multiple components.
routes.js
import { BrowserRouter as Router,Route} from 'react-router-dom';
import React from 'react';
import { FirstConnectedComponent,SecondConnectedComponent } from './App.js';
import Header from './components/header.js';
import Footer from './components/footer.js';
import Login from './components/login.js';
import UserReg from './components/registration.js';
import Home from './components/home';
import requireAuth from './components/authentication';
import PrivateRoute from './components/privateroutes';
const routes=() => (
<Router>
<div>
<Header />
<Route exact path="/" render={ props => <div><FirstConnectedComponent /><SecondConnectedComponent /></div>} />
<Route path="/login" component={PrivateRoute(Login) } />
<Route path="/register" component={ UserReg } />
<Route path="/home" component={ requireAuth(Home)} />
<Footer />
</div>
</Router>
)
export default routes;
In the above code I already applying authguard to routes having single components.But I don't know how to be applied into routes having multiple components.
privateroute
import { connect } from 'react-redux';
import React from 'react';
import { withRouter } from 'react-router';
export default function PrivateRoute(Component) {
class AuthenticatedComponent extends React.Component {
componentWillMount() {
console.log(this.props.loginStatus);
this.checkAuth();
}
checkAuth() {
if (this.props.loginStatus==1) {
this.props.history.push(`/home`);
}
}
render() {
return this.props.loginStatus!=1
? <Component { ...this.props } />
: null;
}
}
function mapStateProps(state) {
return {
loginStatus:state.loginDetails.status
}
}
return connect(mapStateProps)(withRouter(AuthenticatedComponent));
}
Upvotes: 1
Views: 1871
Reputation: 4671
react-router-dom
If useNavigate
not working, use useHistory
App.js
import React from 'react'
import { BrowserRouter as Router, Route, Routes } from 'react-router-dom';
import AuthGuard from "./Routes/AuthGuard";
function App() {
return (
<div className='App'>
<Router>
<Routes>
<Route path='/' element={<Home />} />
<Route path='/contact' element={<Contact />} />
<Route path='/guest-page' element={<AuthGuard isGuest={true}><h1>Guest Page</h1></AuthGuard>} />
<Route path='/protected-page' element={<AuthGuard requireToken={true}><h1>ProtectedPage</h1></AuthGuard>} />
</Routes>
</Router>
</div>
);
}
export default App;
AuthGuard.js
import { Route, useNavigate } from "react-router-dom";
import { useLayoutEffect } from "react";
const ProtectedRoute = ({requireToken, guest, children, ...rest}) => {
console.log(requireToken, guest, children, rest);
const navigate = useNavigate();
const hasToken = false;
let hasAccess = (!requireToken || (requireToken && hasToken));
let navigateTo = '/?login-rquired=true';
if(guest) {
hasAccess = !hasToken;
navigateTo = '/?guest=true';
console.log("Guest > hasAccess: " + hasAccess)
}
if(requireToken){
console.log("requireToken", requireToken)
}
useLayoutEffect(()=>{
if (!hasAccess) {
console.log("Not allowed");
navigate(navigateTo);
}
},[])
return (
<>{ hasAccess ? children : "Login required" }</>
)
}
export default ProtectedRoute;
Upvotes: 0
Reputation: 281656
Instead of using render
prop use the component
prop as you have used the same in PrivateRoute
and wrap the render function with PrivateRoute
HOC like
const routes=() => (
<Router>
<div>
<Header />
<Route exact path="/" component={PrivateRoute(props => <div><FirstConnectedComponent /><SecondConnectedComponent /></div>)} />
<Route path="/login" component={PrivateRoute(Login) } />
<Route path="/register" component={ UserReg } />
<Route path="/home" component={ requireAuth(Home)} />
<Footer />
</div>
</Router>
)
Upvotes: 1