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

相关推荐
UIUV16 小时前
模块化CSS学习笔记:从作用域问题到实战解决方案
前端·javascript·react.js
aoi16 小时前
解决 Vue 2 大数据量表单首次交互卡顿 10s 的性能问题
前端·vue.js
Kakarotto16 小时前
使用ThreeJS绘制东方明珠塔模型
前端·javascript·vue.js
donecoding16 小时前
TypeScript `satisfies` 的核心价值:两个例子讲清楚
前端·javascript
德育处主任16 小时前
『NAS』在群晖部署一个文件加密工具-hat.sh
前端·算法·docker
cup11316 小时前
【原生 JS】支持加密的浏览器端 BYOK AI SDK,助力 Vibe Coding
前端
用户120391129472616 小时前
使用 Tailwind CSS 构建现代登录页面:从 Vite 配置到 React 交互细节
前端·javascript·react.js
杨进军16 小时前
模拟 Taro 实现编译多端样式文件
前端·taro
阿珊和她的猫17 小时前
React Hooks:革新组件开发的优势与实践
前端·react.js·状态模式
全栈技术负责人17 小时前
AI时代前端工程师的转型之路
前端·人工智能