/* message是用来显示内容的 when是用来控制拦截的时机的(也就是弹框出现的时机) */
//第一种用法 message直接写字符串
{
this.state.isOpen? false: "您确定要离开该页面吗?"
//第三种用法 mesage是函数,并且不是三目运算,则函数必须返回false,并且不能自定义弹框,因为react的显示必须写在render里面,这里的函数rentuen的是false,不是DOM,所以只能只用js的原生弹框来拦截
2.useHistory().block
触发机制: 浏览器的返回和前进按钮被点击
用到的页面,其组件在路由或者在任何地方不能使用高阶组件(也就是不能再被别的组件包裹),否则失效
如果用到的页面不是首页,那么进来的页面最好使用push,不能使用replace,否则不好使
import React, {useEffect, useState} from 'react';
import {useHistory} from 'react-router';
import Dialog from '@/components/Dialog'
export default function UserConfirmationTwo(props) {
const {when = false} = props;
const [isShowModal, setIsShowModal] = useState(false);
const history = useHistory();
const [nextLocation, setNextLocation] = useState(null);
const [action, setAction] = useState();
const [unblock, setUnblock] = useState(null);
useEffect(() => {
if (!when || unblock) {
return;
const cancel = history.block((nextLocation, action) => {
if (when) {
setIsShowModal(true);
setNextLocation(nextLocation);
setAction(action);
return false;
setUnblock(() => {
return cancel;
}, [when, unblock]);
useEffect(() => {
return () => {
unblock && unblock();
}, []);
function onConfirm() {
unblock && unblock();
if (action === 'PUSH') {
history.push(nextLocation);
} else if (action === 'POP') {
history.goBack();
} else if (action === 'REPLACE') {
history.replace(nextLocation);
props.closeStopRouteDialog(1);
setIsShowModal(false);
function onCancel() {
props.closeStopRouteDialog(0); //点击取消和确定的事件
setIsShowModal(false);
return (
{isShowModal && <Modal
title="是否返回?"
width='450'
visible={isShowModal}
confirm={()=>onConfirm()}
close={onCancel}
</Modal>}
3.pushState popState
触发机制:浏览器的返回和前进按钮被点击
缺点: 没缺点了,js原生的
<html lang="en">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
margin:0;
padding:0;
.menu{
width: 100px;
height: 40px;
font-size: 30px;
line-height: 40px;
text-align: center;
border:1px solid #000000;
float: left;
margin-left: 50px;
user-select: none;
clear: both;
display: none;
.dialog{
width: 100%;
height: 100%;
background: black;
opacity: 0.5;
position: absolute;
top: 0;
left: 0;
display: none;
.container{
width: 500px;
height: 200px;
position: absolute;
z-index: 100;
left:calc(50% - 250px);
top:calc(50% - 100px);
background: #FFFFFF;
padding:24px;
display: flex;
flex-direction: column;
align-items: start;
justify-content: space-between;
.title{
color:#000000;
font-size: 30px;
line-height: 30px;
font-weight: 600;;
.btn{
.btnLeft{
width: 50px;
height: 30px;
background-color:red;
margin-right:395px;;
.btnRight{
width: 50px;
height: 30px;
background-color:chartreuse
</style>
</head>
<div class='menu'>水果</div>
<div class='menu'>蔬菜</div>
<div class='menu'>零食</div>
<div class='menu'>饮料</div>
<p>猕猴桃
地瓜</p>
薯片</p>
果汁</p>
<div class='dialog'>
<div class='container'>
<div class='title'>确定要返回吗</div>
<div class="btn">
<button class='btnLeft'>取消</button>
<button class='btnRight'>确定</button>
<script>
var arr,divs;
let dialog=document.querySelector('.dialog')
init()
function init(){
// 当历史前进或者后退时就会收到这个事件
window.onpopstate=popStateHandler;
arr=Array.from(document.getElementsByTagName("p"));
divs=Array.from(document.querySelectorAll(".menu"));
cancel=document.querySelector('.btnLeft')
ensure=document.querySelector('.btnRight')
arr[0].style.display="block";
for(var i=0;i<divs.length;i++){
divs[i].onclick=clickHandler;
cancel.addEventListener('click',handleClick)
ensure.addEventListener('click',handleClick)
function clickHandler(){
var index=divs.indexOf(this);
// history.pushState({state:1},"","#"+this.innerHTML);
// 在历史记录列表中增加数据,后面的#内容标示当前跳转部分
history.pushState({index:index}, "", document.URL);
changeMenu(index);
function popStateHandler(){
console.log(history.state);
// changeMenu(history.state.index)
dialog.style.display='block'
function changeMenu(index){
for(var i=0;i<arr.length;i++){
if(i===index){
arr[i].style.display="block";
}else{
arr[i].style.display="none";
function handleClick(e){
if(e.target.innerHTML==='确定'){
dialog.style.display='none'
console.log('点击了确定')
location.href='http://www.baidu.com'
return ;
dialog.style.display='none'
console.log('点击了取消')
// window.location.href='http://www.baidu.com'
</script>
</body>
</html>