React 代码分割后组件重复加载怎么办?

上官世英 阅读 94

我在用 React 的 lazy + Suspense 做路由级别的代码分割,但发现每次切换到同一个路由时,组件都会重新加载,导致状态丢失。明明已经加载过一次了,为什么还会重复执行?是不是我写法有问题?

这是我的写法:

const LazyPage = React.lazy(() => import('./LazyPage'));

function App() {
  return (
    <Suspense fallback="Loading...">
      <Routes>
        <Route path="/page" element={<LazyPage />} />
      </Routes>
    </Suspense>
  );
}

切换到 /page 再切走,回来就又 loading 一次,控制台也看到模块被重新请求了。是不是 webpack 没缓存?还是我漏了什么配置?

我来解答 赞 7 收藏
二维码
手机扫码查看
2 条解答
西门云霞
这问题多半是你路由配置的问题,React.lazy 本身没问题。直接在路由外层包个 memo 或者用 React 的 keep-alive 实现。或者换个思路,试试 react-router 的 unstable_TrackedState 组件。


import { memo } from 'react';

const MemoizedLazyPage = memo(LazyPage);

function App() {
return (
<Suspense fallback="Loading...">
<Routes>
<Route path="/page" element={<MemoizedLazyPage />} />
</Routes>
</Suspense>
);
}


别忘了检查下 webpack 配置里的 chunkFilename,加上 [contenthash] 确保缓存生效。这些问题折腾起来真够呛,祝你好运。
点赞
2026-03-26 07:04
淑然
淑然 Lv1
兄弟,你这个问题很常见。问题不在 webpack 缓存,而在 React Suspense 的位置。

你把 Suspense 放在了 Routes 外面,这意味着每次路由切换,Suspense 组件本身可能会重新挂载,导致内部的 lazy() 重新执行。虽然 webpack 本身会缓存 chunk,但浏览器这边该请求还是得请求。

解决方案:把 Suspense 放到 Routes 里面去。

function App() {
return (
<Routes>
<Route path="/page" element={
<Suspense fallback="Loading...">
<LazyPage />
</Suspense>
} />
</Routes>
);
}


这样每个路由都有自己的 Suspense 边界,组件卸载后再回来不会重新触发 lazy。

如果还不行,可以给 Suspense 加个 key 强制重新挂载:

<Suspense fallback="Loading..." key={location.pathname}>
<LazyPage />
</Suspense>


不过加 key 这种做法有点暴力,会导致每次切路由都重新加载,一般不建议。

另外检查一下你的 webpack 配置,确保 output 用了 contenthash 命名:

output: {
filename: '[name].[contenthash].js',
chunkFilename: '[name].[contenthash].chunk.js',
}


这样能让浏览器正确缓存分割后的 chunk。

你先试试把 Suspense 移到 Route 里面,基本就能解决了。
点赞
2026-03-16 15:01