React router用hooks读取routeName、根据routeName跳转
React router用hooks读取routeName、根据routeName跳转
在迁移Vue至React的过程中遇到了一些路由相关的问题,在Vue项目中经常会使用routeName,毕竟使用path太长了,也记不住,我自己看了看React router也没有发现routeName相关的信息,可能是我没有找到,或者React没有这个概念吧。
在Vue中这样的写法比较常见
const router = new Router({
routes: [{
path: '/smart-mail',
name: 'SmartMailBox',
redirect: '/smart-mail/no-mail',
component: SmartMailBox,
children: [{
path: 'new/:ts',
name: 'MailNew',
component: smartMailNew,
},
{
path: 'info',
name: 'MailDetail',
component: smartMailInfo,
children: [{
path: 'view/:uid/:ts',
name: 'MailView',
component: smartMailView,
},
{
path: 'reply/:uid/:ts',
name: 'MailReply',
component: smartMailReply,
},
{
path: 'reply-all/:uid/:ts',
name: 'MailReplyAll',
component: smartMailReply,
},
{
path: 'forward/:uid/:ts',
name: 'MailForward',
component: smartMailReply,
},
{
path: 'draft/:uid/:ts',
name: 'ReplyOrForwardDraft',
component: smartMailReply,
},
{
path: 'empty/:uid/:ts',
name: 'MailEmpty',
component: smartMailEmpty,
},
{
path: 'new-draft/:uid/:ts',
name: 'MailDraft',
component: smartMailNew,
},
],
},
],
},
],
});
需要跳转就使用routeName,避免长长的path
this.$router.push({
name: 'MailView',
params: {
uid: 'xxx',
}
})
迁移到React时可以这样做
// routes.js
export default [
{
path: "/smart-mail/no-mail",
component: NoMail
},
{
path: "/smart-mail/new/:ts",
component: MailNew,
routeName: 'MailNew'
},
{
path: "/smart-mail/info/:uid",
component: MailDetail,
routes: [
{
path: "/smart-mail/info/view/:uid/:ts/:keyword?",
component: MailView,
routeName: 'MailView',
exact: false,
},
{
path: "/smart-mail/info/reply/:uid/:ts",
component: MailReply,
routeName: 'MailReply',
},
{
path: "/smart-mail/info/replyAll/:uid/:ts",
component: MailReply,
routeName: 'MailReplyAll',
},
{
path: "/smart-mail/info/forward/:uid/:ts",
component: MailReply,
routeName: 'MailForward',
},
{
path: "/smart-mail/info/draft/:uid/:ts",
component: MailReply,
routeName: 'ReplyOrForwardDraft',
},
{
path: "/smart-mail/info/empty/:uid/:ts",
component: MailEmpty,
routeName: 'MailEmpty',
},
{
path: "/smart-mail/info/new-draft/:uid/:ts",
component: MailNew,
routeName: 'MailDraft',
},
]
},
];
上面的routeName是我们为了自己使用而额外增加的字段,我们可以自己写hook来实现根据routeName跳转了
// hook.js
import React from 'react';
import { useHistory, useLocation } from 'react-router-dom';
import routes from "../../routes";
export function useReactRouter() {
function findRoute(routes, routeName) {
for (let item of routes) {
if (item.routeName === routeName) {
return item;
} else if (item.routes){
const result = findRoute(item.routes, routeName);
if (result) {
return result;
}
}
}
}
function findRouteName(routes, pathName) {
for (let item of routes) {
if (item.routes) {
return findRouteName(item.routes, pathName);
} else {
const staticPath = item.path.replace(/\/:\w+\??/g, '');
const isMatch = pathName.indexOf(staticPath) === 0; // 判断是否当前pathName前部分是否与路由的静态地址前部分匹配
if (isMatch) {
return item.routeName;
}
}
}
}
const history = useHistory();
function historyPush(routeName, mailId, keyword = '') {
const route = findRoute(routes, routeName);
if (route) {
const path = route.path.replace(':uid', mailId).replace(':ts', Date.now()).replace(':keyword', keyword);
history.push(path);
} else {
throw new Error(`${routeName} not found`)
}
}
const location = useLocation();
const routeName = useMemo(() => {
return findRouteName(routes, location.pathname);
}, [location, routes]);
return [routeName, historyPush, history];
}
获取routeName
const [routeName] = useReactRouter();
根据当前路由的pathname在自己的静态路由表里面进行匹配,在匹配过程中有部分是动态参数,所以我们在定义路由的时候尽量将path里面的静态部分写在前面,方便匹配,需要注意前面匹配值的唯一性。
根据routeName跳转
const [routeName, historyPush] = useReactRouter();
historyPush.push('MailView', 'xxx');
这个有点类似上面过程的逆过程--根据routeName找到path,然后将传递的参数替换掉动态参数部分。
这样我们就可以类似Vue的方式来进行路由跳转了。
- 分类:
- Web前端
相关文章
支持取消单选组件vue版
原生的单选就是 <input type="radio"/> ,正常情况在 name 相同的单选之间只能选一个,如果只有一个单选框的情况下,一经选中是无法自己取消的,和 阅读更多…
命令式组件Message、Dialog的主流写法分析
这里还是以element-ui为例,那我们就看看里面的Message。 它的dom结构什么的就写在node-modules/element-ui/packages/notification/src/ 阅读更多…
React执行调度流程梳理笔记
触发更新 我们最常见的触发更新的方式就是更新state了,可以分别从类组件和函数组件看看这时会发生什么。 类组件之 setState: 当触发 setState 本质上是调用 enque 阅读更多…
用在线IDE写vue代码
上周末无意中发现了一个新的在线IDE,网址glitch.com,个人感觉很不错,于是顺便关注了下其它的在线IDE,比如codesandbox.io也不错,没有细看,可能自己已经先入为主的喜欢上glit 阅读更多…
使用next.js服务端渲染经历
上周末的时候打算把自己的网站从vue的ssr转换为react的ssr,鉴于之前在vue中是用的原生的ssr,这次想在react中试试框架,所以首选的就是next.js。 第一次用next.js,根据 阅读更多…
2021年的一点工作总结(一)迁移React技术栈
2021年全年的工作总结起来很简单,算是做苦力的一年吧。。。 2021年春节后就开始邮件项目从Vue迁移到React的工作以及富文本编辑器由wangEditor替换成CKEditor。 其实自己 阅读更多…