React Router v6 路由懒加载的2种方式

介绍

React Router v6 的路由懒加载有2种实现方式,1是使用react-router自带的 route.lazy,2是使用React自带的 React.lazy

下面介绍这两种实现方式

注:本文内容针对配置式路由,非约定式路由

0. 相同代码的部分

当前我的依赖包版本 package.json:

json 复制代码
{
  "dependencies": {
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "react-router-dom": "^6.14.0"
  },
  "devDependencies": {
    "@types/node": "^18.15.11",
    "@types/react": "^18.0.28",
    "@types/react-dom": "^18.0.11",
    "@vitejs/plugin-react": "^3.1.0",
    "typescript": "^4.9.3",
    "vite": "^4.2.0"
  },
}

入口文件 src/App.tsx:

tsx 复制代码
import './App.less'
import React from 'react'
import { RouterProvider } from 'react-router-dom'
import { router } from '@/routes'

function App() {
  return <RouterProvider router={router} />
}

export default App

1. React.lazy

依赖 React.lazy + React.Suspense

src/routes/index.tsx:

tsx 复制代码
import React from 'react'
import { createHashRouter, Navigate, RouteObject } from 'react-router-dom'
import Loading from '@/components/Loading'
import BasicLayout from '@/layouts/BasicLayout'
import Page404 from '@/pages/common/404'
import PageLogin from '@/pages/login'

const Page_goodsMng = React.lazy(() => import('@/pages/goods/goodsMng'))

const route404 = {
  path: '*',
  element: <Page404 />,
}

const routes: RouteObject[] = [
  {
    path: '/login',
    element: <PageLogin />
  },
  {
    element: <BasicLayout />,
    children: [
      //// 懒加载代码
      // 商品管理
      {
        path: '/web/company/goods/goodsmgr',
        element: (
          <React.Suspense fallback={<Loading />}>
            <Page_goodsMng />
          </React.Suspense>
        ),
      },
      route404,
    ],
  },
  route404,
]

export default routes

export const router = createHashRouter(routes as any)

2. react-router 自带的 route.lazy

src/routes/index.tsx:

tsx 复制代码
import React from 'react'
import { createHashRouter, Navigate, RouteObject } from 'react-router-dom'
import Loading from '@/components/Loading'
import BasicLayout from '@/layouts/BasicLayout'
import Page404 from '@/pages/common/404'
import PageLogin from '@/pages/login'

const routes: RouteObject[] = [
  {
    path: '/login',
    element: <PageLogin />
  },
  {
    element: <BasicLayout />,
    children: [
      //// 懒加载代码
      // 商品管理
      {
        path: '/web/company/goods/goodsmgr',
        // use react-router route.lazy
        lazy: async () => ({
          Component: (await import('@/pages/goods/goodsMng')).default,
        }),
      },
      route404,
    ],
  },
  route404,
]

export default routes

export const router = createHashRouter(routes as any)

3. 两种方式的区别

React.lazy的方式可以配置加载时的fallback,route.lazy则不支持,也就是说当懒加载的路由内容很大时,route.lazy的方式很有可能有一段时间的白屏。

除了fallback,目前我的体验上还没发现其他的区别,如果还有其他的区别可以评论区讨论一下奥

所以对比来看的话,route.lazy好像没有什么优势

那么我就有疑问了,我觉得fallback这个属于比较基础的功能,react-router既然加入的route.lazy的用法,为什么不加 fallback 呢

4. React Router 为什么不自带fallback功能,要怎么处理?

我找到了一个react-router的issues,问了相同的问题,react-router的作者之一进行了回答,1是印证了react-router确实没有自带fallback的功能,2是回答了作者是如何考虑,以及如果想增加fallback的效果要怎么处理

issues: github.com/remix-run/r...

作者认为:

简单说...这好像就是作者喜好的问题?

React Router 官网的效果是,跳转路由过程中(懒加载过程),当前页面淡出、顶部增加进度条的方式,而非fallback的loading方式

4.1 useNavigation

如果使用route.lazy的方式,可以使用这个 useNavigation 这个hooks,来判断路由是否是loading的状态

经过测试,页面跳转时,navigation为loading

相关推荐
子兮曰10 小时前
jev-ultrafast 深度解析:7 秒订机票的浏览器 Agent 是如何炼成的
前端·后端·agent
子兮曰10 小时前
Jev 爆发一周:7 秒 Agent 背后的 System One 生态与三场争议
前端·后端·ai编程
前端小万10 小时前
写公众号赚了 3000 块后,我做了一款叫 "一键成稿" 的软件
前端·微信小程序
爱勇宝10 小时前
ZCode 开源 24 小时:一份没有历史的账本,回答不了"有没有偷代码"
前端·后端·chatglm (智谱)
三十而立洋11 小时前
Cookie 详解:从产生到安全,一次讲透
前端·javascript
卡布鲁12 小时前
把一个 Vite + Vue3 应用塞进 qiankun (React + Umi3) 主站:十个坑的复盘
前端·javascript·react.js
汉堡大王952713 小时前
Jev:不是聊天机器人, 而是一个智能 if 语句
前端·人工智能·后端
梦想很大很大14 小时前
从运行事实到回归证据:Workrun 的 Telemetry 与 Evaluation 实践
前端·人工智能·后端
计算机魔术师14 小时前
Meta Muse agent 接入 Shopify 的 Shop Pay 实现代理式购物
前端
沙蒿同学14 小时前
我用 Go 搭了一条 AI Agent 流水线:从 1 张商品图到一整套淘宝详情页
前端·javascript·后端