I have a react/redux app, using 'react-router-dom' for routing. I am using the following in my App.js (tags are react-bootstrap, in order to provide private routes. Expected behaviour is to be redirected to /login if, and only if, the user is not logged in (based on the presence of a cookie). Actual behaviour is that the app immediately redirects to /login, even when the user is logged in.
class MainContainer extends Component {
constructor(props) {
super(props);
this.props.loadAuthCookie();
}
PrivateRoute = ({ component: ChildComponent, ...rest }) => {
return (
<Route
{...rest}
render={(props) => {
if (!this.props.auth.loggedIn && !this.props.auth.authPending) {
return <Redirect to="/login" />;
} else {
return <ChildComponent {...props} />;
}
}}
/>
);
};
render() {
const { PrivateRoute } = this;
return (
<Router>
<Container fluid id="root">
<Header />
<Switch>
<Row className="pageContainer">
<Col>
<PrivateRoute exact path="/" component={HomeScreen} />
<Route
exact
path="/clusters/"
component={clusterOverviewScreen}
/>
<Route exact path="/login" component={LoginPage} />
</Col>
</Row>
</Switch>
</Container>
</Router>
);
}
}
const mapStateToProps = (state) => {
return {
auth: state.auth,
};
};
const mapDispatchToProps = (dispatch) => {
return {
loadAuthCookie: () => {
return dispatch(loadAuthCookie());
},
};
};
const RootContainer = connect(
mapStateToProps,
mapDispatchToProps
)(MainContainer);
export default class App extends Component {
render() {
return (
<Provider store={store}>
<RootContainer />
</Provider>
);
}
}
The function this.props.loadAuthCookie dispatches a redux action which pulls the cookie that contains the auth token (if present), and puts it into the state.
Initial state is
{
"authPending": false
"loggedIn": false
"authToken": null
}
Which becomes:
{
"authPending": true
"loggedIn": false
"authToken": null
}
and finally:
{
"authPending": false
"loggedIn": true
"authToken": TOKEN
}
I am relatively new to react. My guess is that by the time the PrivateRoute function runs, the redux action has not yet set the state, and therefore, the PrivateRoute component redirects to the login page. This guess is based on logging props.auth.loggedIn in the private route - this returns false, but by the time the login page to which I am redirected has finished loading, the component props state that this.props.loggedIn is true.I am not sure how to fix this, though.
Edit: loadAuthCookie action:
export const loadAuthCookie = () => (dispatch) => {
dispatch(AuthReducer.setAuthPending());
try {
const cookie = Cookies.get("token");
if (cookie) {
dispatch(AuthReducer.setLoginSuccess(cookie));
}
} catch (err) {
console.log(err);
dispatch(AuthReducer.setLogout());
}
};

this.props.loadAuthCookie();as the first line of render instead of being in the constructor; beforeconst { PrivateRoute } = this;- TonycomponentDidMount() {this.props.loadAuthCookie()}- Hyetigran