[react] react route interception (route guard)

Foreword:
When working on a project recently, if the user does not save the form when returning, it is necessary to intercept the routing jump and give a prompt message whether to exit. I believe that the friends who have done the vue project are no strangers to the routing guard of vue. How to realize it in react? (This sharing is for the v5 version of react-router)

1. Use the Prompt component to complete

Don't gossip and go straight to the dry goods. The react-router package provides us with a component to help us complete the routing guard. It has two parameters when and message.

Since the default pop-up window is very ugly, you need to use antd or meet-react to beautify the pop-up frame. From the values ​​in the table above, we can see that when the value of when is true and the return value of the message function is false, the route will be intercepted and the default pop-up box will not pop up. Not much to say, directly on the example code:

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>
  );
}

2. Use history.block to intercept

insert image description here
By observing the return value, it is not difficult to find that when the return value of the block is false, the routing jump can be intercepted, and the default prompt box will not pop up.

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>
  );
}


Guess you like

Origin blog.csdn.net/hzxOnlineOk/article/details/129790161