React Router v6中如何懒加载loader与action?当前方案是否可行?
React Router v6:直接导入loader、仅懒加载组件的方案可行性分析
你的方案语法上可行,但完全失去了组件懒加载的意义——原因很简单:你通过import {loader as EditContactLoader} from "./Contact/EditContact";同步导入loader时,整个EditContact.jsx模块已经被打包工具(比如Webpack)标记为初始加载的依赖,会在应用启动时就被加载完成。后续用React.lazy加载组件的异步导入,因为模块已经存在于浏览器缓存,不会触发真正的懒加载,等于整个模块没有实现代码分割。
正确实现loader+组件懒加载的方式
要同时实现loader和组件的懒加载,避免模块提前加载,需要通过动态import在路由配置中异步获取loader和组件,而不是同步导入loader:
- 保留
EditContact.jsx的原有导出结构不变 - 修改
Router.js的路由配置:
import React, { lazy, Suspense } from "react"; import { createBrowserRouter } from "react-router-dom"; const Home = lazy(() => import("./Home")); const Root = lazy(() => import("./Root")); // 组件依然用lazy加载,但不要同步导入模块内的任何导出 const EditContact = lazy(() => import("./Contact/EditContact")); export const AppRoutes = createBrowserRouter([ { path: '/', element: <Suspense fallback={<div>加载中...</div>}><Root /></Suspense>, errorElement: <MyError />, children: [ { errorElement: <MyError />, children: [ { index: true, element: <Suspense fallback={<div>加载中...</div>}><Home /></Suspense> }, { path: '/contact/:contactId/edit', // 组件必须用Suspense包裹,否则懒加载时会报错 element: <Suspense fallback={<div>加载编辑页面...</div>}><EditContact /></Suspense>, // 异步加载loader函数 loader: async ({ params }) => { const { loader: editContactLoader } = await import("./Contact/EditContact"); return editContactLoader({ params }); }, // 如果有action,同理异步加载 // action: async ({ request }) => { // const { action: editContactAction } = await import("./Contact/EditContact"); // return editContactAction({ request }); // } }, ], }, ], }, ]);
关键说明
- 浏览器会缓存动态导入的模块,所以不用担心loader触发时重复加载模块
- 所有
lazy加载的组件必须被React.Suspense包裹,用来处理加载过程中的 fallback UI - 这种方式下,只有当用户访问
/contact/:contactId/edit路由时,EditContact.jsx模块才会被加载,真正实现了代码分割和懒加载的效果
内容的提问来源于stack exchange,提问作者Parth Sekar
相关产品推荐
相关产品推荐

