我有一个条件,其中我有3个组件。
A.js B.js C.js
在旧代码中
路线.js
const A = lazy(() => import("../test/A"));
const B = lazy(() => import("../test/B"));
const C = lazy(() => import("../test/C"));
<Route
path="/test"
render={({ match: { url } }) => (
<Switch>
<Route exact path={`${url}/a-test`} component={A} />
<Route exact path={`${url}/b-test`} component={B} />
<Route exact path={`${url}/c-test`} component={C} />
</Switch>
)}
/>
我想实现的目标
通过上面的代码,我们可以得出结论,每次A、B、C的单独构建都会因为懒惰加载而被下载,但我想实现的功能是,我可以将它们三个全部下载,即当下载一个单独的组件时,我可以将它们三个全部下载为一个组件。单建
我的尝试 - 新代码
combine_module.js
import A from "./A";
import B from "./B";
import C from "./C";
const test = {A, B, C};
export default test;
路由.js
const Test = lazy(() => import("../test/combine_module"));
<Route
path="/test"
render={({ match: { url } }) => (
<Switch>
<Route exact path={`${url}/a-test`} component={Test.A} />
<Route exact path={`${url}/b-test`} component={Test.B} />
<Route exact path={`${url}/c-test`} component={Test.C} />
</Switch>
)}
/>
编码
我的问题
我不知道这个方法到底是错还是对,因为我在控制台中没有收到任何与此相关的错误或警告,而是 看到空白屏幕看不到输出所以,请谁能告诉我如何使这个东西正确的,并实现所需的功能。
根据 React.lazy 文档中。
React.lazy需要一个必须调用动态导入()的函数。这必须返回一个Promise,该Promise解析到一个包含React组件的默认导出的模块。
因此 React.lazy
不是一个模块,而是一个特殊的对象 Suspense
可以使用。
一个普通的模块可以用WebPack的 动态导入. 这其中有一个棘手的地方,因为模块可以在组件渲染后加载。所以我们需要做两件事:1)确保组件不被渲染。undefined
2) 当模块加载完毕后,更新组件。
更新很简单,我们可以做一个钩子,将模块设置为加载时的状态。
function useDynamicModule(path) {
const [module, setModule] = useState({});
const [error, setError] = useState();
useEffect(() => {
import(path).then(setModule, setError);
}, []);
return error ? { $error: error } : module.default
}
使用方法
export default function App() {
const Test = useDynamicModule("./CombineModule");
if (!Test) return null;
if (Test.$error) return "Error";
return (
<Router history={history}>
// ...
</Router>
);
}