无法使用带有react-router的props.history.push进行重定向

时间:2019-12-16 18:17:02

标签: reactjs react-router mobx

我实际上正在开发我的第一个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");,它将完成工作。但是我不确定这是一个好习惯。有人可以建议我如何处理这种情况吗?

1 个答案:

答案 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");

编辑:已更新,以包括事件处理程序的正确格式。