在 Next.js 大热之前,React Router 是 React 生态中,最流行的路由库。也是我最喜爱的路由库。不过随着版本的迭代,React Router 变得越来越庞大了。他的复杂度已经快要比得上一个框架了。
所以也不知道现在大家是否还在使用它。
本文主要的目的是结合 Suspense 与 useTransition,来为大家分享一下路由懒加载如何做才是最佳实践。技术点主要包含如下内容
1、React Router v6 基础简介1、React.lazy2、Suspense3、useTransition全文共 3028 字,预计阅读需要花费 6 分钟
1、React Router v6 基础简介
浏览器支持了两种路由方案。分别是 history router 与 hash router。
history router 是目前的主流方案,他相对简洁,我们可以通过 location.pathname 获取到对应的值。
代码语言:javascript复制// history router
xxx.com/article/121
xxx.com/profile
hash router 是指 # 后面的内容。可以通过 location.hash 获取到对应的值。
代码语言:javascript复制// hash router
xxx.com#/article/121
xxx.com#/profile
React Router 中,分别有两个顶层容器组件对应不同的路由模式。
在项目顶层组件中,我们只需要使用对应的组件包裹项目节点,就可以使用对应的路由模式。例如,我们的 demo 项目使用了 BrowserRouter
代码语言:javascript复制ReactDOM.createRoot(document.getElementById('root')).render(
)
然后我们就可以在 App 中使用
子路由的配置,我们使用如下语法来完成
代码语言:javascript复制
path 表示当前路由,element 表示当前路由所对应需要渲染的组件。
当子路由配置比较多时,我们可以通过抽象的思路,将其中的配置项抽离成为数组,然后通过 map 遍历来实现功能
代码语言:javascript复制const routerConfig = [{
path: 'tasks',
element: DashboardTasks
}, {
...
}]
代码语言:javascript复制{routerConfig.map((item, index) => {
} /> ))} ✓如果还有其他更细节的逻辑,请结合正常的需求和 JS 逻辑完善补充,切勿生搬硬套。例如,Route 还支持子组件嵌套,那么这里的逻辑会变得更复杂 两种常见的路由跳转方案 我们可以使用 Link 组件来实现跳转,它类似与一个 a 标签,是一个正常的 UI 组件,因此我们只需要把他放到跳转按钮应该存在的位置即可。 代码语言:javascript复制import { Link } from "react-router-dom"; function UsersIndexPage({ users }) { return ( {users.map((user) => ( {user.name} ))}Users
);
}
另外一种方式就是利用 js 来控制跳转。React Router v6 中,提供了新的 hook 来支持这种跳转。
代码语言:javascript复制import {useNavigate} from 'react-router-dom'
function Motion() {
const navigate = useNavigate()
function __handler() {
navigate('/use/01')
}
return (
)
}
export default Motion;
虽然 React Router v6 非常复杂,不过利用我们刚才提到的知识点,已经可以勉强搭建一个小型应用了。
2、React.lazy
当项目变得庞大时,我们可以通过 React.lazy 来进行拆包。有 React.lazy 引入的组件会单独的打成一个包。如果我们的每一个页面组件都使用它来引入,那么,主包的大小就不会随着页面变多也变大。
这是首屏优化的重要手段之一。
我们可以单独引入一个组件
代码语言:javascript复制import React from 'react';
const OtherComponent = React.lazy(() => import('./OtherComponent'));
function MyComponent() {
return (
);
}
在新的 React 版本中,可以直接将其当做正常的组件使用即可,不会报错。
代码语言:javascript复制 path="xxx" element={ /> 也可以在刚才抽离出来的配置文件中引入。 代码语言:javascript复制import {lazy} from 'react' export const navigation = [{ path: '', name: 'home', component: lazy(() => import('./pages/home')) }, { path: 'motion', name: 'react motion', component: lazy(() => import('./pages/00_motion')) }, { ... }] 如果我们不担心在加载时的白屏时间过长,那么这样做就可以了。 i通常情况下也不会太长,大多数页面代码都非常小,一闪而过就加载成功了 3、Suspense 当然,更保险和稳妥的做法是,使用 Suspense 做一层兜底。Suspense 可以一定程度上拦截可能会发生的报错行为,并且我们有机会在加载页面时,显示一个 Loading 过程。 代码语言:javascript复制