将 React.Lazy 用于服务(非组件)类型的代码

问题描述 投票:0回答:3

根据文档,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>; }>'.
reactjs lazy-loading
3个回答
3
投票

如果您检查

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
    })
  }
}

这将允许延迟加载和可能的代码分割。


2
投票

如果我们想触发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>
  );
}

0
投票

我的动态导入解决方案

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;
  }
}

© www.soinside.com 2019 - 2024. All rights reserved.