问题
I am using passport.js and jwt token to handle the user authentication state in my react app. After the user logs-in, I store the token in localStorage and so depending on whether there's a token or not in the localStorage, I will updated the isAuthenticated state property.
Now, when a guest user (non-authenticated) user, opens the app, he should not be able to access the home-page of the app.
So I devided the routes that the guest user can access and the authenticated user can access to two different variable guestLinks and authLinks.
And depending on the isAuthenticated property, I will display one of those.
App.js
class App extends Component {
render() {
const authLinks = (
<Switch>
<Route
exact
path="/"
name="Login Page"
render={props => <Login {...props} />}
/>
<Route
exact
path="/404"
name="Page 404"
render={props => <Page404 {...props} />}
/>
<Route
exact
path="/500"
name="Page 500"
render={props => <Page500 {...props} />}
/>
<Route
path="/home"
name="Home"
render={props => <DefaultLayout {...props} />}
/>
</Switch>
);
const guestLinks = (
<Switch>
<Route
exact
path="/"
name="Login Page"
render={props => <Login {...props} />}
/>
<Route
exact
path="/register"
name="Register Page"
render={props => <Register {...props} />}
/>
<Route
exact
path="/404"
name="Page 404"
render={props => <Page404 {...props} />}
/>
<Route
exact
path="/500"
name="Page 500"
render={props => <Page500 {...props} />}
/>
</Switch>
);
const currentState = store.getState();
console.log(
"currentState.auth.isAuthenticated: ",
currentState.auth.isAuthenticated
);
return (
<Provider store={store}>
<HashRouter>
<React.Suspense fallback={loading()}>
{console.log(currentState.auth.isAuthenticated)}
{/* TODO: Not sure if this always works. If after the user logsin he gets a blank page and he has to reload to be redirected to home then
this way of routing may need to modified */}
{currentState.auth.isAuthenticated ? authLinks : guestLinks}
</React.Suspense>
</HashRouter>
</Provider>
);
}
}
Notice this line:
{currentState.auth.isAuthenticated ? authLinks : guestLinks}
So after the user logs in, (so he is authenticated), he is redirected to the home-page:
class Login extends Component {
constructor() {
super();
this.state = {
email: "",
mot_de_passe: "",
errors: ""
};
this.onChange = this.onChange.bind(this);
this.onSubmit = this.onSubmit.bind(this);
}
componentDidMount() {
// If the user has already logged-in and he attempts to access the login page this will redirect him to home
if (this.props.auth.isAuthenticated) {
this.props.history.push("/home");
}
}
//This runs when the component receives new properties
componentWillReceiveProps(nextProps) {
// After the user has logged-in this will redirect him to home
if (nextProps.auth.isAuthenticated) {
this.props.history.push("/home");
}
if (nextProps.errors) {
this.setState({ errors: nextProps });
}
}
onChange(e) {
this.setState({
[e.target.name]: e.target.value
});
}
onSubmit(e) {
console.log(e);
// Since it's a form, we don't want it to have its default behavior
e.preventDefault();
const userInfo = {
email: this.state.email,
password: this.state.mot_de_passe
};
// Any action that we bring-in is going to be stored inside props
//this.props.loginUser(userInfo, this.props.history);
this.props.loginUser(userInfo);
}
render() {
return (
<div className="app flex-row align-items-center">
<Container>
<Row className="justify-content-center">
<Col md="8">
<CardGroup>
<Card className="p-4">
<CardBody>
<Form noValidate onSubmit={this.onSubmit}>
<h1>Se connecter</h1>
<p className="text-muted">
Connectez-vous à votre compte
</p>
<InputGroup className="mb-3">
<InputGroupAddon addonType="prepend">
<InputGroupText>
<i className="icon-user"></i>
</InputGroupText>
</InputGroupAddon>
{/* WORK_HERE */}
<Input
name="email"
type="text"
placeholder="Email"
value={this.state.email}
onChange={this.onChange}
/>
</InputGroup>
<InputGroup className="mb-4">
<InputGroupAddon addonType="prepend">
<InputGroupText>
<i className="icon-lock"></i>
</InputGroupText>
</InputGroupAddon>
<Input
name="mot_de_passe"
type="password"
placeholder="Mot de passe"
autoComplete="current-password"
value={this.state.mot_de_passe}
onChange={this.onChange}
/>
</InputGroup>
<Row>
<Col xs="6">
<Button color="primary" className="px-4">
Se connecter
</Button>
</Col>
<Col xs="6" className="text-right">
<Button color="link" className="px-0">
Mot de passe oubliée?
</Button>
</Col>
</Row>
</Form>
</CardBody>
</Card>
<Card
className="text-white bg-primary py-5 d-md-down-none"
style={{ width: "44%" }}
>
<CardBody className="text-center">
<div>
<h2>Bienvenue au Viwone SAV</h2>
<p>
Suivez en temps réel l'évolution des opérations du
service après-vente.
</p>
</div>
</CardBody>
</Card>
</CardGroup>
</Col>
</Row>
</Container>
</div>
);
}
}
The problem is that after he logs-in, he get a blank screen and he has to reload the page in order for the home-page to be successfully displayed.
It seems that the authLinks don't get loaded fast enough for the app to be able to detect the link to the home screen.
回答1:
In your App.js
, get isAuthenticated
value using connect()
so it will re-render with latest value of isAuthencticated
after login and your will see the updated urls
来源:https://stackoverflow.com/questions/60213080/reactjs-problem-with-displaying-home-page-after-user-logs-in