react路由原理解析(react路由拦截(路由守卫))
前言: 最近在做项目时候 ,遇到了返回时候如果用户没有保存表单 ,需要拦截路由跳转,并给出提示信息是否要退出 。相信做过vue项目的小伙伴都对vue的路由守卫并不陌生 ,react中如何实现呢?(本分享是针对react-router的v5版本)
一 、使用Prompt组件来完成闲话不多说直接上干货 ,react-router包里边给我们提供了一个组件 ,来帮助我们完成路由守卫 。它有两个参数when和message 。
参数名称 类型 作用 when boolean true 弹窗
false顺利跳转 message function或者字符串 函数返回true就顺利跳转 ,false停止跳转
字符串就弹窗字符串并停止跳转 。 when值 message值 路由是否跳转 是否弹出默认框 false 无论message是函数返回任何值还是message是字符串后边结果都一样 是 否 true message是字符串 否 是 true message是函数返回值true 是 否 true message是函数返回值是字符串 否 是 true message是函数返回false 否 否由于默认弹窗非常不好看 ,所以 ,要借助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返回值 路由是否跳转 是否弹出默认框 true 是 否 false 否 否 string 否 是通过观察返回值不难发现当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> ); }创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!