我实际上正在开发我的第一个React应用程序,并且在登录后仍无法进行重定向。
该项目已使用create-react-app v.2创建,我使用mobx来处理状态管理,并且我试图使用react-router来浏览该应用程序。
这是我的代码以及到目前为止我所做的:
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;
在Login.js中,我要注入LoginBusinessStore的实例,该实例具有我的业务逻辑。 如您所见,当我发送凭据时,它会触发LoginBusinessStore的sendCredentials方法:
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;
如果登录成功,我想做的就是重定向到特定的路由。我尝试使用this.props.history.push("/contact");
,但收到错误消息:
Cannot read property 'history' of undefined
如果我改用window.location.replace("/contact");
,它将完成工作。但是我不确定这是一个好习惯。有人可以建议我如何处理这种情况吗?
答案 0 :(得分:1)
您需要通过组件树传递历史道具,以便在LoginBusinessStore
中访问它们。
在您的Home
组件中,您需要将历史道具传递给您的Login
组件:
<Login history={this.props.history} />
然后在您的Login
组件中,需要将历史记录对象传递到您的sendCredentials
函数中:
<button onClick={() => this.props.loginBusinessStore.sendCredentials(this.props.history)} className="btn btn-primary">Go!</button>
最后,在LoginBusinessStore
中,您需要调整函数以接受历史对象并使用它:
sendCredentials = (history) => {
调整试图重定向到的行:
history.push("/contact");
编辑:已更新,以包括事件处理程序的正确格式。