2016-06-09 73 views
1

我遇到了react-router问题。React路由器取决于React组件的状态

我的路线文件如下:

const routes = (
<Route path="/" component={App}> 
    <IndexRoute component={HomePage}/> 
    <Route path="registration" component={Registration}> 
     <Route path="/registration-step-one" component={RegistrationStepOne} /> 
     <Route path="/registration-step-two" component={RegistrationStepTwo}/> 
     <Route path="/registration-step-three" component={RegistrationStepThree}/> 
     <Route path="/registration-step-four" component={RegistrationStepFour}/> 
    </Route> 
    <Route path="reset-password" component={PasswordReset} /> 
</Route> 
); 

我有一个很大的组成部分注册其中有四个步骤。通过点击提交按钮,状态改变,下一步显示。

注册组件代码:

onButtonClick(name, event) { 
    event.preventDefault(); 
    switch (name) { 
     case "stepFourConfirmation": 
      this.setState({step: 1}); 
      break; 
     case "stepTwoNext": 
      this.setState({step: 3, errors: {}}); 
      break; 
     case "stepThreeFinish": 
      this.setState({step: 4}); 
      break; 
     default: 
      this.setState({step: 2, errors: {}}); 
    } 
} 

render() { 
    const languageReg = this.props.currentLanguage.default.registrationPage; 

    let formStep = ''; 
    let step = this.state.step; 
    switch (step) { 
     case 1: 
      formStep = (<RegistrationFormStepOne user={this.state.user} 
               onChange={this.setUser} 
               onButtonClick={this.onButtonClick} 
               onClick={this.changeStep} 
               errors={this.state.errors}/>); 
      break; 
     case 2: 
      formStep = (<RegistrationFormStepTwo user={this.state.user} 
               onChange={this.setUser} 
               onButtonClick={this.onButtonClick} 
               onClick={this.changeStep} 
               errors={this.state.errors}/>); 
      break; 
     case 3: 
      formStep = (<RegistrationFormStepThree user={this.state.user} 
                onFileChange={this.onFileChange} 
                onButtonClick={this.onButtonClick} 
                onClick={this.changeStep} 
                errors={this.state.errors} 
                files={this.state.files} 
                fileChosen={this.state.selectedFile}/>); 
      break; 

     default: 
      formStep = (<RegistrationFormStepFour user={this.state.user} 
                onChange={this.setUser} 

                onChangeCheckboxState={this.changeCheckboxState} 
                emailNotificationsState={this.state.user.emailNotifications} 
                termsState={this.state.user.terms} 
                smsNotificationsState={this.state.user.smsNotifications} 

                onButtonClick={this.onButtonClick} 
                onClick={this.changeStep} 
                errors={this.state.errors}/>); 
    } 

    return (
     <div className="sidebar-menu-container" id="sidebar-menu-container"> 

      <div className="sidebar-menu-push"> 

       <div className="sidebar-menu-overlay"></div> 

       <div className="sidebar-menu-inner"> 
        <div className="contact-form"> 
         <div className="container"> 
          <div className="row"> 
           <div className="col-md-10 col-md-offset-1 col-md-offset-right-1"> 
            {React.cloneElement(formStep, {currentLanguage: languageReg})} 
           </div> 
          </div> 
         </div> 
        </div> 
       </div> 
      </div> 
     </div> 
    ); 
} 

但是,如果我在一个例如第三步,我点击返回浏览器我重定向到主页。有没有什么办法可以让路由器只进入前一步ant而不是主页?或者,如果我使用状态来更改表单步骤,则无法完成此操作?

回答

1

你可以用routerWillLeave钩子来做到这一点。在official react-router documentation上阅读更多关于它的信息。

这里是你能做什么:

componentDidMount =() => { 
    this.props.router.setRouteLeaveHook(this.props.route, this.routerWillLeave); 
    //or this.context.router, depending on your app 
} 

routerWillLeave = (nextLocation) => { 
    if (this.state.step > 1) { 
    this.setState({step: this.state.step-1}); 
    return false; 
    } 
} 

以上将阻止路线的变化,如果step变化大于一。而是调用setStatestep减1,强制执行前一步的渲染。如果step等于1,那么在历史中实际返回到上一页可能是有意义的,因为在步骤1之前没有先前的步骤。


您可能也有兴趣实际上可以追溯到前一页如果用户填写了一些数据表单之前要求的路线休假确认对话框(以防止其丢失)。在这种情况下,你可以添加到上面的代码:

routerWillLeave(nextLocation) { 
    if (this.state.step > 1) { 
    ... 
    } else if (this.hasUnsavedData()) { 
    return "You have unsaved data. Are you sure you want to leave?" 
    } 

hasUnsavedData()一些自定义的功能,你会写检查所有的表单元素,并返回false只有当所有输入字段为空,否则true

+0

我得到_TypeError:无法读取属性'setRouteLeaveHook'undefined_ – Boky

+0

尝试'this.context.router .....'而不是。所以用'context'替换'props'。 – Chris

+0

我已添加'RegistrationPage.contextTypes = { router:PropTypes.object };'使上下文可用。但现在我得到_Uncaught TypeError:无法读取undefined_的属性'step'。 – Boky