异步路由(路由懒加载)

344 阅读2分钟

异步路由

React做异步路由,需要将React的lazy方法和<Suspense></Suspense>组件配合进行使用。

<Suspense> 组件是 React 中用于处理异步操作一个高级功能。它主要用于在组件加载过程中显示一个 fallback UI,直到所有依赖的数据或组件加载完成。<Suspense> 组件接受一个 fallback 属性,属性可以是任何有效的 React 节点,例如一个简单的文本、一个加载动画、一个占位符组件等,用于在组件加载期间显示。

主要作用:

  • 延迟渲染:<Suspense> 允许在组件树中延迟渲染某些组件,直到它们所需的资源(如数据、代码片段等)加载完成。
  • 统一的加载状态管理:通过 <Suspense>,可以在多个组件中共享同一个加载状态,避免每个组件都需要单独处理加载状态。
  • 提升用户体验:在数据或组件加载期间显示一个友好的加载指示器(如加载动画、占位符等),可以显著提升用户体验。

示例

有一个异步加载的组件 LazyComponent,可以使用 <Suspense> 来包裹它,并提供一个 fallback UI。<div>Loading...</div> 将在 LazyComponent 加载完成前显示。

// App.jsx
import { lazy, Suspense } from "react"
// 使用 lazy 函数将组件懒加载,告诉 React 在第一次需要渲染组件时才去加载它。
const LazyComponent = lazy(() => import('./LazyComponent.jsx'));
function App() {
  return (
    <>
      {/* 使用 <Suspense></Suspense> */}
      <Suspense fallback={<div>Loading...</div>}>
        <LazyComponent />
      </Suspense>
    </>
  );
}
export default App;
// 异步加载的组件,LazyComponent.jsx
import React from 'react';

const LazyComponent = () => {
  return (
    <div>
      <h2>Lazy Component</h2>
      <p>这个组件是懒加载的</p>
    </div>
  );
};

export default LazyComponent;

调慢网速可以清晰看见刷新页面时,LazyComponent组件异步加载完成之前,先展示了Loading...文本。

2.gif

多个懒加载组件:可以在一个 <Suspense> 组件中包裹多个懒加载组件,这样它们可以共享同一个加载状态。

// App.jsx
import { lazy, Suspense } from "react"
// 使用 lazy 函数将组件懒加载,告诉 React 在第一次需要渲染组件时才去加载它。
const LazyComponent = lazy(() => import('./LazyComponent.jsx'));
const About = lazy(() => import('./about/index.jsx'));
function App() {
  return (
    <>
      {/* 使用 <Suspense></Suspense> */}
      <Suspense fallback={<div>Loading...</div>}>
        <LazyComponent />
        <About />
      </Suspense>
    </>
  );
}
export default App;

引入lazy方法,实现路由懒加载。注意:使用路由懒加载一定要使用<Suspense></Suspense>标签将组件包裹起来,否则会报错。

React中懒加载组件导致的路由跳转错误(踩坑)

lazy函数用于懒加载,即当用到的时候才会开始加载,但是路由跳转是立刻完成的,React会直接报错。解决方案是使用React提供的Suspense组件解决,这个还能实现时加载显示加载动画的功能。

错误用法:

// App.jsx
import React, {lazy} from "react"
import { Routes, Route, Link } from "react-router-dom"
const Shop = lazy(() => import('./Shop.jsx'))
const Home = lazy(() => import('./Shop.jsx'))
export default function App() {
  return (
    <>
      <div>
        <Link to='/home'>首页</Link>
        <Link to='/shop'>商品</Link>
      </div>
      <Routes>
        <Route path="/home" element={<Home></Home>}></Route>
        <Route path="/shop" element={<Shop></Shop>}></Route>
      </Routes>
    </>
  )
}

2.gif

正确用法:

// App.jsx
import React, { lazy, Suspense } from "react"
import { Routes, Route, Link } from "react-router-dom"
const Shop = lazy(() => import('./Shop.jsx'))
const Home = lazy(() => import('./Home.jsx'))
export default function App() {
  return (
    <>
      <div>
        <Link to='/home'>首页</Link>
        <Link to='/shop'>商品</Link>
      </div>
      <Routes>
        <Route path="/home" element={<Suspense><Home /></Suspense>}></Route>
        <Route path="/shop" element={<Suspense><Shop /></Suspense>}></Route>
      </Routes>
    </>
  )
}

2.gif