React-Router-Dom v6配合Suspense使用报无效React子元素错误如何解决
问题判断
你的判断完全正确。
报错的核心原因是:React.lazy()的返回值是特殊的懒加载组件定义对象,不是可直接渲染的React元素。react-router-dom v6 的Route组件的element属性,要求传入实例化后的JSX元素,而非组件本身的定义(不管是普通组件还是lazy包装的懒加载组件都遵循这个规则)。你直接把lazy()执行后返回的对象传给element,React尝试渲染这个普通对象时就会抛出你看到的错误——错误信息里提到的带$$typeof, _payload, _init键的对象,正是lazy方法返回的组件定义对象。
另外你当前写法还有一个隐藏问题:把lazy()调用写在map渲染循环里,每次组件重渲染都会重新执行lazy、重新触发动态import,会导致懒加载缓存失效,产生不必要的性能损耗。
修复方案
- 第一步:提前初始化所有懒加载组件,不要在渲染循环、render函数内部调用
React.lazy()。实际项目中可以直接把懒加载组件定义写在路由配置数组中:
import { lazy, Suspense } from 'react' import { Routes, Route } from 'react-router-dom' import LoadingDots from './components/LoadingDots' // 提前初始化懒加载组件,仅执行一次 const AppsListPage = lazy(() => import("./features/apps/AppsListPage")) // 其余路由懒加载组件同理提前定义 const routes = [ { path: '/apps', component: AppsListPage }, // 其余路由配置 ]
- 第二步:路由渲染时,不要直接把组件对象传给element,而是将懒加载组件写成JSX标签的形式传入:
function AppRouter() { return ( <Suspense fallback={ <div className="center-div"> <LoadingDots /> </div> } > <Routes> {routes.map((route) => { const LazyPage = route.component return ( <Route path={route.path} key={route.path} element={<LazyPage />} /> ) })} </Routes> </Suspense> ) }
如果需要给路由组件传递自定义props、或者处理嵌套路由,直接在<LazyPage />标签上追加属性即可,用法和普通组件完全一致。
内容的提问来源于stack exchange,提问作者BeginnerDev
相关产品推荐
相关产品推荐

