Reactjs react路由器中的“自定义休假”对话框
我有一个表单,用户可以在其中编辑内容。如果用户有一些未保存的更改并且想要离开页面,我想给他一个自定义对话框,询问他是否确定。如果是,则应继续导航,并重置表单更改标志,否则用户应停留在页面上 在这里,您可以检查我当前的高阶组件,它正在检查此条件。它正在工作,但函数Reactjs react路由器中的“自定义休假”对话框,reactjs,react-native,react-router,Reactjs,React Native,React Router,我有一个表单,用户可以在其中编辑内容。如果用户有一些未保存的更改并且想要离开页面,我想给他一个自定义对话框,询问他是否确定。如果是,则应继续导航,并重置表单更改标志,否则用户应停留在页面上 在这里,您可以检查我当前的高阶组件,它正在检查此条件。它正在工作,但函数leave返回一个字符串,然后路由器将在本机警报中显示该文本 有没有办法在这里显示我的自定义对话框?我还可以得到一个回调或类似的警报,这样我就可以调度一个事件,告诉存储器最新的更改并不重要 import React, {Component
leave
返回一个字符串,然后路由器将在本机警报中显示该文本
有没有办法在这里显示我的自定义对话框?我还可以得到一个回调或类似的警报,这样我就可以调度一个事件,告诉存储器最新的更改并不重要
import React, {Component, PropTypes} from "react";
import connectRouter from "./connectRouter";
import { connect } from "react-redux";
import {injectIntl, intlShape} from "react-intl";
export default function confirmLeave(RouteTargetComponent) {
@injectIntl
@connectRouter
@connect((state, routing) => {
return {
studies: state.studies
};
})
class ConfirmLeaveHOC extends Component { // HOC = Higher Order Component
static propTypes = {
router: PropTypes.object.isRequired,
route: PropTypes.object.isRequired,
dispatch: PropTypes.func.isRequired,
intl: intlShape.isRequired,
studies: PropTypes.object.isRequired,
};
leave = () => {
if (this.props.studies.isChanged) {
// lets stop the navigation
return this.props.intl.formatMessage({ id: "confirmLeave" });
}
// continue the navigation
return true;
}
componentDidMount() {
this.props.router.setRouteLeaveHook(this.props.route, this.leave.bind(this));
}
render() {
// render the component that requires auth (passed to this wrapper)
return (<RouteTargetComponent {...this.props}/>);
}
}
return ConfirmLeaveHOC;
}
import React,{Component,PropTypes}来自“React”;
从“/connectRouter”导入connectRouter;
从“react redux”导入{connect};
从“react intl”导入{injectIntl,intlShape};
导出默认函数confirmLeave(RouteTargetComponent){
@注射剂
@连接路由器
@连接((状态、路由)=>{
返回{
研究:国家研究
};
})
类ConfirmLeaveHOC扩展组件{//HOC=高阶组件
静态类型={
路由器:PropTypes.object.isRequired,
路由:PropTypes.object.isRequired,
调度:需要PropTypes.func.isRequired,
intl:intlShape.isRequired,
研究:需要PropTypes.object.isRequired,
};
离开=()=>{
if(this.props.studies.ischange){
//让我们停止导航
返回此.props.intl.formatMessage({id:“confirmLeave”});
}
//继续导航
返回true;
}
componentDidMount(){
this.props.router.setRouteLeaveHook(this.props.route,this.leave.bind(this));
}
render(){
//呈现需要身份验证的组件(传递到此包装器)
返回();
}
}
返回ConfirmLeaveHOC;
}
由于无法自定义浏览器对话框,您必须呈现单独的组件(例如引导模式),并使用回调来确定单击了哪个按钮以及要采取的操作
实际上,我遇到了与您最近面临的问题相同的问题,我能够通过使用routerWillLeave
和使用来自另一个组件的回调来解决这个问题
表单组件
不幸的是,像这样的定制对话框的实现是一件非常麻烦的事情。我必须在这里使用3个变量来正确控制所需的行为:
-当用户确认要导航出去时,必须防止逻辑再次运行。具体来说,当运行回调时,我们执行waitingForConfirm
,则this.context.router.push(route.pathname)
将再次运行(!),但由于我们已确认导航,因此必须防止此逻辑再次运行routerWillLeave
-检查是否有任何输入字段已更改(没有理由询问是否没有要保存的更改)\u hasUnsavedChanges()
-如果用户单击了单击保存
,请不要要求确认-我们知道我们要离开保存
\u show=(回调)=>{
this.callback=回调;
this.setState({show:true});
}
_隐藏=()=>{
this.setState({show:false});
this.callback=null;
}
_dialogAction=(输入)=>{
if(this.callback){
这个.回调(输入);
}
这个;
}
render(){
返回(
...
对
不
);
}
显然,您必须自定义上述代码片段以适合您的应用程序,但希望它能提供一些解决问题的方法。一种不太复杂且更具前瞻性的方法是在组件上使用setRouteLeaveHook。根据react路由器v2.4.0
import React from 'react'
import { withRouter } from 'react-router'
const Page = React.createClass({
componentDidMount() {
this.props.router.setRouteLeaveHook(this.props.route, () => {
if (this.state.unsaved)
return 'You have unsaved information, are you sure you want to
leave this page?'
})
}
render() {
return Stuff
}
})
export default withRouter(Page)
感谢
this.context.router.push(route.pathname)代码>帮助了我很多
_show = (callback) => {
this.callback = callback;
this.setState({show: true});
}
_hide = () => {
this.setState({show: false});
this.callback = null;
}
_dialogAction = (input) => {
if (this.callback) {
this.callback(input);
}
this._hide();
}
render() {
return (
...
<Button onClick={this._dialogAction.bind(this, true)}>Yes</Button>
<Button onClick={this._dialogAction.bind(this, false)}>No</Button>
);
}
import React from 'react'
import { withRouter } from 'react-router'
const Page = React.createClass({
componentDidMount() {
this.props.router.setRouteLeaveHook(this.props.route, () => {
if (this.state.unsaved)
return 'You have unsaved information, are you sure you want to
leave this page?'
})
}
render() {
return Stuff
}
})
export default withRouter(Page)