I'm actually working on my very first React app and I'm struggling with the redirect after login.
The project has been created with create-react-app v.2, I use mobx to handle the state management, and I'm trying to use react-router to navigate through the app.
Here is my code and what I have done so far :
Index.js :
ReactDOM.render((<Provider loginBusinessStore={new LoginBusinessStore()} >
<BrowserRouter>
<App />
</BrowserRouter>
</Provider>), document.getElementById('root'));
App.js:
class App extends Component {
render() {
return (
<div className="container-fluid" >
<Switch>
<Route exact path='/' component={Home} />
<Route path='/contact' component={Contact} />
<Route path='/about' component={About} />
</Switch>
</div>
);
}
}
export default App;
Home.js:
class Home extends Component {
render() {
return (
< div className="bg">
<div className="row" >
<div className="col-sm-4"> <TextHome /> </div>
<div className="col-sm-4"> <Login /></div>
<div className="col-sm-4"> </div>
</div>
</div>
);
}
}
export default Home;
In Login.js, I'm injecting an instance of LoginBusinessStore, where I have my business logic. As you see when I send my credentials, it triggers the method sendCredentials of LoginBusinessStore:
class Login extends Component {
onChangePassword = (event) => { this.props.loginBusinessStore.setPassword(event.target.value) }
onChangeEmail = (event) => { this.props.loginBusinessStore.setEmail(event.target.value) };
displayErrorMessage = () => {
if (this.props.loginBusinessStore.loginRequestStatus == "ERROR") {
return (<p>Oups, nous avons un problème de connexion. Rééssaie plus tard. </p>)
} if (this.props.loginBusinessStore.loginRequestStatus == "WRONG_CREDENTIALS") {
return (<p>La combinaison email/ mot de passe n'est pas correcte.</p>)
}
}
render() {
return (
<div>
<div className="form-group">
<label htmlFor="email">Email address</label>
<input type="email" onChange={this.onChangeEmail} className="form-control" id="email" aria-describedby="emailHelp" />
<small id="emailHelp" className="form-text text-muted">We'll never share your email with anyone else.</small>
</div>
<div className="form-group">
<label htmlFor="password">Password</label>
<input type="password" onChange={this.onChangePassword} className="form-control" id="password" />
</div>
<button onClick={this.props.loginBusinessStore.sendCredentials} className="btn btn-primary">Go!</button>
<p>Créer un compte</p>
<br />
<div className= "error"> {this.displayErrorMessage()} </div>
</div>
);
}
}
export default inject("loginBusinessStore")(observer(Login));
class LoginBusinessStore {
email;
password;
token = "noTokenYet";
loginRequestStatus = "PENDING"; // "OK", "WRONG_CREDENTIALS", "ERROR"
setToken(myToken) {
this.token = myToken;
};
setEmail(myEmail) {
this.email = myEmail;
};
setPassword(myPassword) {
this.password = myPassword;
};
setLoginRequestStatus(myLoginRequestStatus) {
this.loginRequestStatus = myLoginRequestStatus;
}
sendCredentials = () => {
console.log("enter sendCredential");
const axios = require("axios");
axios.post("http://localhost:8080/authenticate/",
{ username: this.email, password: this.password }).
then(res => {
console.log(res.data);
this.setToken(res.data.token);
this.setLoginRequestStatus("OK");
this.props.history.push("/contact");
// window.location.replace("/contact");
}).catch(error => {
if (error.message.includes("401")) {
console.error('Combinaison email/mdp non valide', error)
this.setLoginRequestStatus("WRONG_CREDENTIALS");
} else {
console.error('Login impossible', error)
this.setLoginRequestStatus("ERROR");
}
})
};
}
decorate(LoginBusinessStore, {
loginRequestStatus: observable,
sendCredentials: action
})
export default LoginBusinessStore;
What I'd like to do is to redirect to a specific route if the login has been successfull. I tried with this.props.history.push("/contact");
but get an error:
Cannot read property 'history' of undefined
If I use instead window.location.replace("/contact");
it does the job. But I'm not sure it's a good practice. Can someone advise me on how to handle this situation?