返回

巧用导航守卫打造个性化的React路由拦截弹窗

前端

在前端开发中,我们经常会遇到需要拦截表单未保存时跳转页面的需求。这需要我们在React应用中实现优雅且个性化的拦截提示弹窗。本文将向您介绍多种实现自定义 React 路由拦截弹窗的方法。

1. 使用 React-Router 提供的 Prompt 组件

React-Router 提供了一个名为 Prompt 的组件,可以方便地拦截导航。其使用方式如下:

import { Prompt } from "react-router-dom";

const MyComponent = () => {
  const [isBlocking, setIsBlocking] = useState(false);

  const handleClick = () => {
    setIsBlocking(true);
  };

  return (
    <div>
      <button onClick={handleClick}>离开此页</button>
      <Prompt
        when={isBlocking}
        message={() => "您尚未保存数据,是否离开此页?"}
      />
    </div>
  );
};

当用户点击“离开此页”按钮时,isBlocking 状态将变为 true,从而触发 Prompt 组件显示拦截弹窗。

2. 使用 useEffect 监听 history 变化

另一种实现导航拦截的方法是使用 useEffect 监听 history 的变化。其使用方式如下:

import { useEffect, useState } from "react";
import { useHistory } from "react-router-dom";

const MyComponent = () => {
  const [isBlocking, setIsBlocking] = useState(false);
  const history = useHistory();

  useEffect(() => {
    const unlisten = history.listen((location, action) => {
      if (isBlocking) {
        if (action === "POP") {
          history.goBack();
        } else {
          history.block("您尚未保存数据,是否离开此页?");
        }
      }
    });

    return () => {
      unlisten();
    };
  }, [isBlocking, history]);

  const handleClick = () => {
    setIsBlocking(true);
  };

  return (
    <div>
      <button onClick={handleClick}>离开此页</button>
    </div>
  );
};

当用户点击“离开此页”按钮时,isBlocking 状态将变为 true,从而触发 useEffect 监听器。当 history 发生变化时,如果 isBlocking 为 true,则会阻止导航或显示拦截弹窗。

3. 使用自定义导航守卫

除了上述两种方法外,您还可以使用自定义导航守卫来拦截导航。其使用方式如下:

import { useLocation, useNavigate } from "react-router-dom";

const MyNavigationGuard = (to, from, next) => {
  if (isBlocking) {
    next("您尚未保存数据,是否离开此页?");
  } else {
    next();
  }
};

const MyComponent = () => {
  const [isBlocking, setIsBlocking] = useState(false);
  const location = useLocation();
  const navigate = useNavigate();

  useEffect(() => {
    navigate.createPath(location.pathname, MyNavigationGuard);
  }, [location, navigate]);

  const handleClick = () => {
    setIsBlocking(true);
  };

  return (
    <div>
      <button onClick={handleClick}>离开此页</button>
    </div>
  );
};

当用户点击“离开此页”按钮时,isBlocking 状态将变为 true,从而触发自定义导航守卫。如果 isBlocking 为 true,则会显示拦截弹窗。

结论

以上就是实现自定义 React 路由拦截弹窗的多种方法。您可以根据自己的需要选择合适的方法。希望本文能帮助您更好地实现您的项目需求。