道招

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',
    }
})

file 迁移到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的方式来进行路由跳转了。

更新时间:
上一篇:邮箱收件人组件成长历程(三)跨栏拖拽不同数据方案对比下一篇:怎么调试Webpack+React项目,报错basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")怎么办

相关文章

Vue和React hooks实现Select批量选择、选中条数、全选、反选实现对比

批量选择、全选、反选这些功能使用频率还是很高的,下面直接看看Vue和React分别怎么实现吧。 Vue 在使用Vue的时候是很容易实现的,我们以下列数据格式为例: const data 阅读更多…

用在线IDE写vue代码

上周末无意中发现了一个新的在线IDE,网址glitch.com,个人感觉很不错,于是顺便关注了下其它的在线IDE,比如codesandbox.io也不错,没有细看,可能自己已经先入为主的喜欢上glit 阅读更多…

react router页面跳转二次确认弹框及样式、业务逻辑自定义

我们在编辑页面时如果需要跳走通常会需要给用户提示,react router本身已经给了我们这样的功能,我们先看看怎么使用。 初见二次确认弹框 // App.jsx const App = 阅读更多…

Vue2.6.10源码分析(一)vue项目怎么神奇的跑起来的

先看index.html的代码吧 <!DOCTYPE html> <html lang="en"> <head> <meta 阅读更多…

项目Vue转成React hooks可能存在的问题--急需类似setState回调

假设在Vue中有如下三个方法,并且初始时 this.a = ‘a’; this.b = ‘b’; funA() { this.a = '1221&#03 阅读更多…

vue多语言的解决方案不只是 vue-i18n,前端+后端完整解决方案

网上搜很多vue多语言的,一般都是介绍vue-i18n怎么使用,当然这是不错的,但是我们如果只是讲这个的话,只是解决了静态文字的多语言化。 这一部分我们也简单讲一下 npm install 阅读更多…

关注道招网公众帐号
友情链接
消息推送
道招网关注互联网,分享IT资讯,前沿科技、编程技术,是否允许文章更新后推送通知消息。
允许
不用了