动态导入和延迟加载 React 组件
Dynamic Import and Lazy load React Components
我正在尝试在 Tab 组件中加载组件以进行反应。这个想法是有一个 json (或更好的 yaml)与这个语法:
interface TabType {
name: string;
components: string[];
}
interface Templates {
tabs: TabType[];
}
const templateTabsModules: Templates = {
tabs: [
{
name: "Title for Tab 1",
components: ["./components/OneComponent"]
},
{
name: "Title for Tab 2",
components: ["./components/TwoComponent"]
}
]
};
所以在主要组件内部做类似的事情:
<Tabs id="tab">
{templateTabsModules.tabs.map(tab => {
return (
<Tab title={tab.name}>
<p>The component should appears bellow:</p>
<Suspense fallback={<div>Loading</div>}>
{tab.components.map(component => {
const Comp = lazy(() => import(component));
return (<Comp />)
})}
</Suspense>
</Tab>
);
})}
</Tabs>
但是这段代码不起作用,我可以看到,如果我通过 const Comp = lazy(() => import('./components/OneComponent'));
仅将路径用作字符串,它就可以工作,但如果我使用动态变量则不会。
Webpack 正在尽力排除所有您不需要的文件。
我认为如果您之前定义常量并在循环中引用它们应该可以工作
const Comp1 = lazy(() => import('./components/OneComponent'));
const Comp2 = lazy(() => import('./components/TwoComponent'));
...
tabs: [
{
name: "Title for Tab 1",
component: Comp1
},
{
name: "Title for Tab 2",
component: Comp2
}
]
...
<Suspense fallback={<div>Loading</div>}>
{tabs.map(tab => tab.component)}
</Suspense>
我找到了一个可能的解决方案,它可以满足我的需要,而无需在组件之前声明:
<Tabs id="tab">
{templateTabsModules.tabs.map((tab, index) => {
return (
<Tab title={tab.name} key={index}>
<p>The component should appears bellow:</p>
<Suspense fallback={<div>Loading</div>}>
tab.components.map(component => {
const Comp = lazy(() => import(
/* webpackChunkName: "my-chunk-name" */
/* webpackMode: "lazy" */
`${component}`
).then(comp => comp));
return (<Comp />)
})}
</Suspense>
</Tab>
);
})}
</Tabs>
所以 Webpack 可以加载组件并 return 它作为 promise
示例 -> https://codesandbox.io/s/lazy-components-with-react-mix9y
我正在尝试在 Tab 组件中加载组件以进行反应。这个想法是有一个 json (或更好的 yaml)与这个语法:
interface TabType {
name: string;
components: string[];
}
interface Templates {
tabs: TabType[];
}
const templateTabsModules: Templates = {
tabs: [
{
name: "Title for Tab 1",
components: ["./components/OneComponent"]
},
{
name: "Title for Tab 2",
components: ["./components/TwoComponent"]
}
]
};
所以在主要组件内部做类似的事情:
<Tabs id="tab">
{templateTabsModules.tabs.map(tab => {
return (
<Tab title={tab.name}>
<p>The component should appears bellow:</p>
<Suspense fallback={<div>Loading</div>}>
{tab.components.map(component => {
const Comp = lazy(() => import(component));
return (<Comp />)
})}
</Suspense>
</Tab>
);
})}
</Tabs>
但是这段代码不起作用,我可以看到,如果我通过 const Comp = lazy(() => import('./components/OneComponent'));
仅将路径用作字符串,它就可以工作,但如果我使用动态变量则不会。
Webpack 正在尽力排除所有您不需要的文件。
我认为如果您之前定义常量并在循环中引用它们应该可以工作
const Comp1 = lazy(() => import('./components/OneComponent'));
const Comp2 = lazy(() => import('./components/TwoComponent'));
...
tabs: [
{
name: "Title for Tab 1",
component: Comp1
},
{
name: "Title for Tab 2",
component: Comp2
}
]
...
<Suspense fallback={<div>Loading</div>}>
{tabs.map(tab => tab.component)}
</Suspense>
我找到了一个可能的解决方案,它可以满足我的需要,而无需在组件之前声明:
<Tabs id="tab">
{templateTabsModules.tabs.map((tab, index) => {
return (
<Tab title={tab.name} key={index}>
<p>The component should appears bellow:</p>
<Suspense fallback={<div>Loading</div>}>
tab.components.map(component => {
const Comp = lazy(() => import(
/* webpackChunkName: "my-chunk-name" */
/* webpackMode: "lazy" */
`${component}`
).then(comp => comp));
return (<Comp />)
})}
</Suspense>
</Tab>
);
})}
</Tabs>
所以 Webpack 可以加载组件并 return 它作为 promise
示例 -> https://codesandbox.io/s/lazy-components-with-react-mix9y