需求场景: 在页面中表单但凡有编辑的操作,当用户离开页面的时候,需要跳出一个提示框,提醒用户离开当面页面,表单内容会被清空,用户选择取消 会留在当前页面,用户选择确认 则会离开页面。
拿到这个需求的时候,第一个反应就是vue中有路由守卫 ,react是否有类似的呢?尝试着把判断条件放在router的render里去执行,发现render element执行的时候,根本不会打断页面的跳转。查看了下react-router-dom的官网发现,他提供了Prompt 的组件,这个组件可以在离开当前路由的时候,提示用户,并且阻止路由的跳转。
注:react-router-dom v6的版本里竟然移除了这个组件。
简单写了例子,回顾下实现过程吧
入口文件,2个按钮分别跳转对应的路由以及路由的声明
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 App.js import './App.css'; import { BrowserRouter as Router, Switch, Route, Link } from "react-router-dom"; import About from "./pages/About"; import Me from "./pages/Me"; function App() { return ( <div className="App"> <Link to="/about">About</Link> <br></br> <Link to="/me">Me</Link> <div> <p>内容区域</p> <Switch> <Route path="/about"> <About /> </Route> <Route path="/me"> <Me /> </Route> </Switch> </div> </div> ); } export default App;
1 2 3 4 5 6 7 8 9 10 Me.js import React from 'react'; export const Me = () => { return <div> me... </div> } export default Me;
重点还是在About.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 import React, { useState, useCallback, useEffect } from 'react'; import { Prompt } from "react-router-dom"; export const About = () => { const [isChanged, setIsChange] = useState(false); const [text, setText] = useState(""); useEffect(() => { if (text && !isChanged) { setIsChange(true); } }, [isChanged, text]) const onChange = useCallback((e) => { setText(e.target.value); }, []) return ( <div> about... <input onChange={onChange} /> <Prompt when={isChanged} message={(location) => { const status = window.confirm("当前表单未提交,是否要离开当前页面?") if (status) { setIsChange(false); return true; } return false; }} /> </div> ) } export default About;
When: 控制是否弹出提示,true提示,false不提示。
message: 返回true离开页面,false阻止离开页面。
最后效果
我的微信公众号: 梨的前端小屋