【react】react路由拦截(路由守卫)

前言:
最近在做项目时候,遇到了返回时候如果用户没有保存表单,需要拦截路由跳转,并给出提示信息是否要退出。相信做过vue项目的小伙伴都对vue的路由守卫并不陌生,react中如何实现呢?(本分享是针对react-router的v5版本)

一、使用Prompt组件来完成

闲话不多说直接上干货,react-router包里边给我们提供了一个组件,来帮助我们完成路由守卫。它有两个参数when和message。

由于默认弹窗非常不好看,所以,要借助antd或者meet-react来美化弹框。通过上边表格值可知,当when值是true并且message是函数返回值为false时候,才会拦截路由同时,不会弹出默认弹出框。话不多说,直接上实例代码:

import {
    
      Dialog } from '@alifd/meet-react';
import React, {
    
     useEffect, useState} from 'react';
import {
    
     Prompt, useHistory } from 'react-router';

import style from './index.module.scss';

export default function TestPage() {
    
    
  const history = useHistory();
  const [notAllowJump, setNotAllowJump] = useState(true);

  /**
   * 路由拦截
   * @param {*} location string
   * @returns boolean
   */
  function handleRouter() {
    
    
    const list = field.getValue('list');
    const equal = xxxxx(); // 判断两次值是不是一样 
    if (equal) {
    
    
    // 两次值一样,用户没改动数据,直接放行
      return true;
    }
    Dialog.show({
    
    
      centered: true,
      content: '是否保存当前修改数据',
      onOk() {
    
    
      	// 用户需要提交,提交后要放行,先将when置为false,再提交操作
        setNotAllowJump(false);
        xxxxxSubmit(); // 继续提交
      },
      async onCancel() {
    
    
      	// 用户不提交,直接放弃修改返回上一页。将when置为false再返回,注意setNotAllowJump操作是异步的。
        await setNotAllowJump(false);
        history.goBack();
      },
    });
    // 用户有修改,返回false拦截跳转,同时屏蔽掉默认弹出框
    return false;
  }

  return (
    <div className={
    
    style['test-page']}>
      <Prompt when={
    
    notAllowJump} message={
    
    handleRouter} />
      <footer>
        我是页面内容
      </footer>
    </div>
  );
}

二、使用history.block拦截

在这里插入图片描述
通过观察返回值不难发现当block返回值是false时候,能够拦截路由跳转,并且不会弹出默认提示框。

import {
    
     useHistory } from 'react-router';
import {
    
      Dialog } from '@alifd/meet-react';
import React, {
    
     useEffect, useState} from 'react';

import style from './index.module.scss';

export default function TestPage() {
    
    
  const history = useHistory();
  
  useEffect(() => {
    
    
    history.block(() => {
    
    
      Dialog.show({
    
    
        centered: true,
        content: '是否保存当前修改数据',
        onOk() {
    
    
          history.block(() => true); // 放开拦截提交操作,成功后在提交函数内跳出去
          xxxxxSubmit();
        },
        async onCancel() {
    
    
          history.block(() => true);
          history.goBack();
        },
      });
      // 开启路由拦截同时阻止默认弹出框
      return false;
    });
  }, [history]);

  return (
    <div className={
    
    style['test-page']}>
      <footer>
        我是页面内容
      </footer>
    </div>
  );
}


猜你喜欢

转载自blog.csdn.net/hzxOnlineOk/article/details/129790161