Reputation: 2408
I am currently implementing an authentication/login flow with React
and React Router V4
. But I am struggling to find a working redirect "schema" to implement my idea.
The situation is as follows:
My current implementation:
Entry Component
export default class Entry extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<Router>
<Routes />
</Router>
);
}
}
Routes Component (authentication checking takes place here)
class Routes extends PureComponent {
componentDidMount() {
this.props.loadUser(); // async method (redux) loads the actual logged in user
}
render() {
return (
<Switch>
<Route path="/login" render={() => (!this.props.user.username ? <LoginPage {...this.props}/> : <Redirect to="/app" />)} />
<Route path="/app" render={() => (this.props.user.username ? <AppPage {...this.props} /> : <Redirect to="/login" />)} />
<Route exact path="/" render={props => <Redirect to="/app" />} />
</Switch>
);
}
}
export default Routes;
App component (nested routing here)
export default class App extends React.Component {
constructor(props) {
super(props);
}
render() {
const { match, user, logout } = this.props;
return (
<Switch>
<Route path={`${match.path}/about`} component={About} />
<Route path={`${match.path}`} component={Home} />
</Switch>
);
}
}
The Problem now occurs when the following is happening:
/app/about
this.props.user.username
is null
/login
this.props.loadUser()
has updated the redux store and this.props.user.username
is not null
anymore and then the user gets redirected to /app
but he originally wanted to visit /app/about
.So the line which makes me headaches is
<Route path="/login" render={() => (!this.props.user.username ? <LoginPage {...this.props}/> : <Redirect to="/app" />)} />
How should I handle this specific approach so that the user gets redirected to the URL he/she originally wanted to visit ?
Maybe my overall approach is a little bit weird.
Thanks in advance, I appreciate every help :)
Upvotes: 4
Views: 11534
Reputation: 10307
Since you're using react-router v4 I recommend going to their great docs about this topic. Here
const PrivateRoute = ({ component: Component, ...rest }) => (
<Route {...rest} render={props => (
fakeAuth.isAuthenticated ? (
<Component {...props}/>
) : (
<Redirect to={{
pathname: '/login',
state: { from: props.location }
}}/>
)
)}/>
)
const AuthExample = () => (
<Router>
<div>
<AuthButton/>
<ul>
<li><Link to="/public">Public Page</Link></li>
<li><Link to="/protected">Protected Page</Link></li>
</ul>
<Route path="/public" component={Public}/>
<Route path="/login" component={Login}/>
<PrivateRoute path="/protected" component={Protected}/>
</div>
</Router>
);
Upvotes: 11