根据文档,React.Lazy 需要包装在
<suspense>
中。我可以使用 React.Lazy
延迟加载导出函数的服务吗?
const actionsList = React.lazy(() => import('@pkg/actions-list-service'));
并且 action-List-service 在 .ts 文件中导出一个函数。 React 推荐的延迟加载非组件类型代码的方式是什么? 这是我尝试延迟加载服务代码时遇到的错误我收到此错误:
Type 'Promise<{ default: typeof import("D:/services/actions-list-service/dist/types"); useActionsList: () => (itemElement: HTMLElement | null | undefined) => readonly ActionsListItem[]; }>' is not assignable to type 'Promise<{ default: ComponentType<any>; }>'.
如果您检查
React.lazy()
的来源,您会发现它是面向组件渲染的,正如您所猜测的那样。为了延迟加载某些内容,您可以使用异步导入:
// example code, to show possible solution
const moduleMap = {
module1: () => import('./module1.js'),
module2: () => import('./module2.js')
}
function doSomething(moduleName) {
// You might call this one in useEffect() for example
const module = moduleMap[moduleName]
if (module) {
module().then(({default: actualModule, member1}) => {
// use the module members
})
}
}
这将允许延迟加载和可能的代码分割。
如果我们想触发React Suspense加载器,那么我们必须提供一个组件来加载独立库。
例如,我想延迟加载 html5-qrcode
Html5Qrcode
模块,它的大小为 314K(gzipped 93.5K)。
我们创建一个加载器组件,它将有一个
onLoaded
回调道具,它只返回如下模块:
import { useEffect } from 'react';
import { Html5Qrcode } from 'html5-qrcode/esm/html5-qrcode';
export default function Html5QrcodeLoader({ onLoaded }) {
useEffect(() => {
onLoaded(Html5Qrcode);
}, []);
return null;
}
然后我们使用
React.lazy
导入该组件,例如:
const Html5QrcodeLoader = React.lazy(() =>
import(
'@components/Html5QrcodeLoader' /* webpackChunkName: "Html5QrcodeLoader" */
)
);
现在我们可以像这样使用我们的组件的加载器:
export default function QrCodeScanner() {
const [Html5Qrcode, setHtml5Qrcode] = useState();
useEffect(() => {
if (!Html5Qrcode) {
return;
}
// Use lazy loaded module Html5Qrcode
}, [Html5Qrcode]);
const handleHtml5QrcodeLoaded = module => {
// Careful, always do it using a function,
// else the module itself will be initialized!
setHtml5Qrcode(() => module);
};
if (!Html5Qrcode) {
// Lazy load it
return <Html5QrcodeLoader onLoaded={handleHtml5QrcodeLoaded} />;
}
log('Html5Qrcode loaded');
// Now render
return (
<div>
<div>QrCodeScanner</div>
</div>
);
}
google-libphonenumber
(必须延迟加载的重型库)
phoneutil.ts
/** Dynamic import for code splitting/lazy loading. */
const googleLibphoneNumberModule = () => import('google-libphonenumber');
let phoneUtil: libphonenumber.PhoneNumberUtil;
const modulePromise = googleLibphoneNumberModule().then(({ default: { PhoneNumberUtil } }) => {
phoneUtil = PhoneNumberUtil.getInstance();
});
export async function isPhoneNumberValid(phone: string) {
try {
await modulePromise;
return phoneUtil.isValidNumber(phoneUtil.parseAndKeepRawInput(phone));
} catch (error) {
return false;
}
}