Skip to content

Instantly share code, notes, and snippets.

@rcanepa
Last active March 2, 2023 08:29
Show Gist options
  • Save rcanepa/b4ce0dff8d85b357504e04b03e69ac66 to your computer and use it in GitHub Desktop.
Save rcanepa/b4ce0dff8d85b357504e04b03e69ac66 to your computer and use it in GitHub Desktop.
Private routes with React Router v4
function PrivateRoute ({component: Component, authenticated, ...rest}) {
return (
<Route
{...rest}
render={(props) => authenticated === true
? <Component {...props} />
: <Redirect to={{pathname: '/login', state: {from: props.location}}} />}
/>
)
}
<Route path='/' exact component={Home} />
<Route path='/login' component={Login} />
<Route path='/register' component={Register} />
<PrivateRoute authenticated={this.state.authenticated} path='/invoices' component={Invoices} />
@jermsam
Copy link

jermsam commented Jul 30, 2018

hello, what's the proper way to authenticate a route in react-router-dom? With this snippet I get two errors that I do not get how to solve:

Can't call setState (or forceUpdate) on an unmounted component.
looks like the authUser state gets set after the checkNotNull(obj) function is run.
Kindly help me with any of these. Thank you.
https://gist.github.com/jermsam/88c6dcc04f7db3dd323a668215a797d8

@jermsam
Copy link

jermsam commented Jul 30, 2018

The error persists even when I use the react-private-route module recommended by @hansfpc

@krigulson
Copy link

Using Redux if anyone needs it..

import React from 'react';
import { Route, Redirect } from 'react-router-dom';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';

const PrivateRoute = ({ component: Component, auth: auth, ...rest }) => (
  <Route
    {...rest}
    render={props =>
      auth.isAuthenticated === true ? (
        <Component {...props} />
      ) : (
        <Redirect to="/login" />
      )
    }
  />
);

PrivateRoute.propTypes = {
  auth: PropTypes.object.isRequired
};

const mapStateToProps = state => ({
  auth: state.auth
});

export default connect(mapStateToProps)(PrivateRoute);

nice one @bradtraversy
does the exact thing what i needed. when user is logged in then route is available and when user is on Private route and logs out then user is redirected aswell. Other similar solutions somehow didn't worked for me. But your solution works!

Many thanks!

@tarang9211
Copy link

Can this be implemented via cookies?

@juliettegodyere
Copy link

Hello, I am having some issues with the React Router Dom PrivateRoute. The private route redirects to the login page even when the user is authenticated. I can't figure out the exact thing that I am doing wrong. Please see the routers and the privateRoute code below.

My Route
<Switch>
<Route path="/login" render={(props) => <Login onLogin={this.handleLogin} {...props} />}></Route>
<Route path="/signup" component={Signup}></Route>
<PrivateRoute exact path="/" authenticated={this.state.isAuthenticated} component={Dashboard} handleLogout = {this.handleLogout}></PrivateRoute>
<PrivateRoute exact path="/dashboard" authenticated={this.state.isAuthenticated} component={Dashboard} handleLogout {this.handleLogout}></PrivateRoute>
<PrivateRoute exact path="/members" authenticated={this.state.isAuthenticated} component={MemberList} handleLogout={this.handleLogout}></PrivateRoute>
<PrivateRoute exact path="/members/new" authenticated={this.state.isAuthenticated} component={NewMember} handleLogout={this.handleLogout}></PrivateRoute>
<PrivateRoute exact path="/members/view" authenticated={this.state.isAuthenticated} component={ViewMember} handleLogout={this.handleLogout}></PrivateRoute>
<Route component={NotFound}></Route>
</Switch>

const PrivateRoute = ({ component: Component, authenticated, ...rest }) => (
<Route
{...rest}
render={props =>
authenticated ? (
<Component {...rest} {...props} />
) : (
<Redirect
to={{
pathname: '/login', state: { from: props.location }
}} /> ) } /> );

@adil-waqar
Copy link

Hey guys, this question might sound weird but I am really very confused with this, so bear with me.

In the below code,

function PrivateRoute ({component: Component(-------Here we are using "C" but when we are passing the prop we are using "c" and if memory serves when destructuring the right side of the : gets its value assigned to the left side of the colon in the object and also in the bottom when we are typing the component we are also using "C" how and why is this working????---------- ) , authenticated, ...rest}) {
return (
<Route
{...rest}
render={(props) => authenticated === true
? <Component {...props} />(-------------Here we are using again "C"----------------------)
: <Redirect to={{pathname: '/login', state: {from: props.location}}} />}
/>
)
}

<Route path='/' exact component={Home} />
<Route path='/login' component={Login} />
<Route path='/register' component={Register} />
<PrivateRoute authenticated={this.state.authenticated} path='/invoices' component={Invoices} />  (-------------Here we are using again "c"----------------------)

Are my concepts wrong or is there some magic at play?

I have this same confusing. Can anyone help?

@orenaksakal
Copy link

orenaksakal commented Dec 27, 2020

@adil-waqar
@kanlanc

You can rename while destructuring thats what is happening there like so {actualName: newName},
so we receive component and rename it to be Component after desctucturing with {component: Component}
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment