react router页面跳转二次确认弹窗及样式、业务逻辑自定义
我们在编辑页面时如果需要跳走通常会需要给用户提示,react router本身已经给了我们这样的功能,我们先看看怎么使用。
初见二次确认弹窗
// App.jsx
const App = () {
return (
-
Home
-
Write
);
}
export default App;
在WriteMail组件里面我们加上Prompt组件并且设置when我嫩就会有二次确认弹窗了,也就是从/write页面跳转时会需要进行确认
// WriteMail.jsx
const WriteMail = () => {
function redirectMsg(location, type) {
return type + ': Go to ' + location.pathname;
}
return (
Write
redirectMsg(a, '外层')}/>
);
};
export default WriteMail;
效果如下
自定义二次确认弹窗
功能是有了,但是界面也太丑了吧。不用担心,react router当然支持自定义二次弹窗啊。
我们的二次确认弹窗其实通过给BrowserRouter(或者HashRouter)组件设置属性来自定义的,它默认的就是window.confirm
官方是这么说的
{
// this is the default behavior
const allowTransition = window.confirm(message);
callback(allowTransition);
}}
/>
所以我们需要修改下App.jsx了,我们这里引入antd的Modal做弹窗
// App.jsx
const App = () {
const getUserConfirmation = (message, callback) => {
Modal.confirm({
title: message,
onCancel: () => {
callback(false);
},
onOk: () => {
callback(true);
}
});
}
return (
-
Home
-
Write
);
}
export default App;
是不是很完美?
进阶
这个getUserConfirmation属性是在BrowserRouter组件上的,一般我们的项目可能只在组件树的外层才会有一层BrowserRouter,而业务组件一般是在其里面的Route组件的里面,即
如果我们需要在getUserConfirmation里面出来当前WriteMail相应的业务逻辑怎么弄?(比如弹窗提示文案是“您即将跳转,是否需要保存草稿?”,我们需要执行WriteMail里面的保存草稿逻辑。)
我们很容易想到,如果能将Router组件,放到WriteMail里面就好了,那样我们就能将getUserConfirmation写在WriteMail,执行对应的逻辑就很容易了。
我们尝试下在WriteMail加一层BrowserRouter,同时需要将业务逻辑(编辑组件)放置于内层的Route下,即多了一层路由
// WriteMail.jsx
function WriteMail(props) {
const [value, setValue] = useState('');
const getUserConfirmationInWrite = (message, callback) => {
Modal.confirm({
title: message,
onCancel: () => {
callback(false);
},
onOk: () => {
callback(true);
}
});
}
return (
Write
redirectMsg(a, '外层')}/>
-
First
-
Second
first
redirectMsg(a, '内层')}/>
setValue(e.target.value)}/>
second
)
}
现在我们有两层路由了,我们可以设置成不同的getUserConfirmation ,App.jsx用默认的。 完整的代码如下
// App.jsx
const App = () {
return (
-
Home
-
Write
);
}
export default App;
// WriteMail.jsx
function WriteMail(props) {
const [value, setValue] = useState('');
const [count, setCount] = useState(0);
const getUserConfirmationInWrite = (message, callback) => {
console.log('getUserConfirmationInWrite -> ', );
Modal.confirm({
title: message,
onCancel: () => {
setCount(count => count - 1);
callback(false);
},
onOk: () => {
setCount(count + 1);
callback(true);
}
});
}
return (
Write
redirectMsg(a, '外层')}/>
-
First
-
Second
first
redirectMsg(a, '内层')}/>
setValue(e.target.value)}/>
second
)
}
export default WriteMail;
现在我们在WriteMail里面的getUserConfirmationInWrite就可以写组件内的业务逻辑(setCount)了。
上面的代码里面我们有两个Prompt,分别表示从/write开头的路径和/write/first路径跳转时会进行二次确认。 实测发现:
- 从/write切换至/write/first,会有外层提示,从 并且我们可以看到外层提示
- 从/write/first切换至/write,会先有外层提示,点击确认后再出现内层提示;如果外层提示时点击了取消,则不会再有内层提示了。
PS: 我们会发现在点击二次确认时浏览器的url可能已经提前变更了,及时在二次确认弹窗时点击的是取消,但是好在内容是带确认后才会变更。