Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Reactjs react路由器中的“自定义休假”对话框_Reactjs_React Native_React Router - Fatal编程技术网

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)