我遇到了react-router的问题。
我的路线文件如下:
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>
);
}
但是,如果我在第三步,我在浏览器中单击,我将重定向到主页。有没有办法让路由器只进入上一步而不是主页?或者,如果我使用状态来更改表单步骤,则无法完成?
答案 0 :(得分: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
更改大于1,上述操作将阻止路由更改。而是调用setState
并将step
减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
。