前言: 当我们在操作页面时,如果页面中的某些内容被改变,我们又不希望操作者离开页面时数据丢失或者重置,这时我们通常会在取消按钮上绑定一个点击事件来提醒操作者,当前的操作可能会导致已填写的数据丢失,通常情况出现在表单提交时。但有一种例外就是操作人直接切换路由这个时候就需要我们用到今天所讲的Prompt组件
大致的效果图如下:
Prompt是react-router为我们提供的一个组件,他允许我们在切换路由的时候给出合理的提示来规避一些额外的情况。
参数也非常的简单
when
:设置是否启用Prompt功能。比如表单页未填写时,就不需要离开确认。message
:string。设置Prompt提示内容message
:function。此时返回参数分为true/false,即bool类型。返回false就继续停留在当前页面,返回true则跳转到新页面。
所以当我们遇到需要Prompt
处理的情况时我们可以将Prompt封装作为一个组件使用,具体的实例如下:
import { Modal } from "antd";
import React, { Component } from "react";
import { withRouter } from "react-router-dom";
import { Prompt } from "react-router";
/**
* 路由拦截组件
* 监听页面跳转是否需要保存信息
*/
class RouterPrompt extends Component {
constructor(props) {
super(props);
this.state = {
isBlock: this.props.isBlock,
};
}
getDerivedStateFromProps(nextProps, prevState) {
console.log(nextProps, prevState, "nextProps, prevState");
if (nextProps.isBlock !== prevState.isBlock) {
return { isBlock: nextProps.isBlock };
}
return null;
}
render() {
return (
<Prompt
when={this.state.isBlock}
message={(location, action) => {
const that = this;
Modal.confirm({
title: "信息还没保存,确定离开吗?如果点击确认,您的更改将会丢失。",
content: "",
okText: "确定",
cancelText: "取消",
onOk: () => {
this.setState({isBlock:false},()=>{
this.props.history.push(location)
})
},
onCancel: () => {
return false
},
});
return false;
}}
/>
);
}
}
export default withRouter(RouterPrompt);
代码逻辑:
- 通过
withRouter
高阶组件包裹得到this.props.history
对象 - 接受一个外部传进来的props,这个
props
中含有一个控制状态的属性 - 当我们触发了路由的跳转就会执行
Prompt
组件,组件内部通过函数判断是否进行跳转 - 返回false则不进行跳转,反之则使用
this.props.history.push
进行跳转
在父组件中的使用也非常简单,下面是一个简单的例子:
//再父组件中引用
import RouterPrompt from './RouterPrompt';
// 再父组件中使用
{this.state.isBlock && <RouterPrompt isBlock={this.state.isBlock}></RouterPrompt>}
希望可以帮助到被这种变态需求困惑的人。