I have the following react functional component to help support authentication required routes with react-router.
const PrivateRoute = ({ component: Componen
The functional component is the render
function, therefore:
class PrivateRoute extends React.Component {
render() {
const {component: Component, ...rest} = this.props;
return (
<Route {...rest} render={props => (
isAuthenticated() ? (
<Component {...props}/>
) : (
<Redirect to={{
pathname: '/login',
state: {from: props.location }
}}/>
)
)}/>
);
}
}
or, written a bit more readable:
class PrivateRoute extends React.Component {
render() {
const {component: Component, ...rest} = this.props;
const renderRoute = props => {
if (isAuthenticated()) {
return (
<Component {...props} />
);
}
const to = {
pathname: '/login',
state: {from: props.location}
};
return (
<Redirect to={to} />
);
}
return (
<Route {...rest} render={renderRoute}/>
);
}
}
A nice, clean refactor by extending the Route
component:
class PrivateRoute extends Route {
render() {
return isAuthenticated()
? super.render()
: <Redirect to={{
pathname: '/login',
state: {from: props.location}
}}/>;
}
}
If you use this, you have to wrap your <PrivateRoute/>s
in a <Switch/>
, as below. Otherwise, you will have duplicate redirects and the page will fail to load.
<Router>
<Navbar/>
<SideDrawer/>
<Switch>
<Route path="/tokens" component={Login}/>
<PrivateRoute exact path="/" component={ExampleComponent}/>
<PrivateRoute path="/users" component={Users}/>
<PrivateRoute path="/software" component={Software}/>
</Switch>
</Router>