我有2个组件,我想使用类似
的延迟加载来加载所有组件const A = lazy(() => import("../test/A"));
const B = lazy(() => import("../test/B"));
这将创建2个单独的包,并在需要时将其导入。
但是,我要创建一个捆绑包,当该捆绑包加载时,我应该能够使用上述两个组件。
我也不想创建包含上述两个组件的单个组件,因为我想为它们两个提供单独的路由
我试图做这样的事情 https://codesandbox.io/s/eager-raman-mdqzc?file=/src/App.js
可以请人解释一下这种功能是否可能,如果可以,那么我怎么做和做错了
答案 0 :(得分:2)
从文档中
借助
React.lazy
函数,您可以将动态导入呈现为常规组件。
React.lazy
采用必须调用动态import()
的函数。这必须返回一个Promise
,该解析为包含默认导出的包含React组件的模块。然后,应该在
Suspense
组件内部呈现惰性组件,这使我们可以在等待惰性组件加载时显示一些后备内容(例如加载指示符)。您可以将
Suspense
组件放置在惰性组件上方的任何位置。您甚至可以使用单个Suspense
组件包装多个惰性组件。
因此,如果您想使用lazy()
来包装模块,则必须具有一个组件作为模块的default
属性。因此,它不允许您自动使用将命名导出作为组件的模块。 但是,您可以轻松做出将已命名的导出转换为默认导出的承诺,并将其包装为惰性:
// in comboModule.js:
export A from '../test/A'
export B from '../test/B'
// in the code that needs lazy modules
const A = lazy(() => import('./comboModule').then((module) => ({default: module.A})))
const B = lazy(() => import('./comboModule').then((module) => ({default: module.B})))
请注意,我们必须在传递给import
的初始化函数内调用lazy
,否则导入将立即开始。 lazy
的部分好处是,您可以等到父组件呈现惰性组件后再进行加载。但是,import()
应该缓存第一次导入的结果,并且只加载一次代码。
在初始化函数中,我们使用then
将import()
的结果从类似Promise({A: <Component>, B: <Component>})
的内容转换为懒惰期望的初始化函数:Promise({default: <Component>})
现在我们有两个惰性组件,它们都来自一个模块文件。
资源:
答案 1 :(得分:1)
您可以使用Suspense等待两者。有两个捆绑包,但是您可以等待加载它们两者
import React, { Suspense, lazy } from 'react';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
const Home = lazy(() => import('./routes/Home'));
const About = lazy(() => import('./routes/About'));
const App = () => (
<Router>
<Suspense fallback={<div>Loading...</div>}>
<Switch>
<Route exact path="/" component={Home}/>
<Route path="/about" component={About}/>
</Switch>
</Suspense>
</Router>
);
答案 2 :(得分:0)
我写了一个效用函数来概括@garrett-motzner 在他的回答中所说的内容:
import {lazy} from 'react';
export const multiLazy = moduleLoaderArray => {
const promises = Promise.all(moduleLoaderArray.map(loader => loader()));
return moduleLoaderArray.map((m, index) =>
lazy(() => promises.then(results => results[index]))
);
}
像这样的魅力:
const [A, B] = multiLazy([
() => import("../test/A"),
() => import("../test/B"),
]);
所以不需要创建中间组件文件(当然除了实用功能)
我选择这种语法是为了尽可能接近 React.lazy
语法,但如果喜欢和经常使用,可以修改它以获得 multiLazy(['../test/A', '../test/B'])
。