React Suspense 延迟加载没有回退

React Suspense lazy loading without fallback

我想延迟加载我的组件以减小我的初始包大小,并使用 React 路由器使用代码拆分来动态获取组件。

但是,当使用 React Suspense 时,它​​们会强制您使用后备加载。
这行不通:

const lazyLoadComponent = Component =>
    props => (
        <Suspense> // Missing fallback property
            <Component {...props} />
        </Suspense>
    );

在我的例子中,我从服务器渲染 html,所以我不想使用微调器。
这会在我的屏幕上造成无用的闪烁! 即:

在我的例子中,html 对应于加载的反应组件。

是否有任何已知的 hack 可以轻松解决此问题(除了为任何复制 html (!!) 的路由创建加载程序外,顺便说一下,这会使延迟加载变得无用)。

我对“强迫”我们添加一个加载程序感到有点不满,我不明白强制性决定背后的逻辑。

尝试在the docs

中使用代码拆分

fallback props只是一个React元素,你可以为null设置它。

const MyLazyComponent= React.lazy(() => import('./MyComponent'));

<Suspense fallback={null}>
    <MyLazyComponent />
</Suspense>

我在 Github 上为此创建了一个问题:https://github.com/facebook/react/issues/19715

目前没有使用 React-Router / React 的干净解决方案。
然而,在使用并发模式的未来版本中可以预见到这一点。正如 Dan Abramov 所提到的:

Regarding your concrete feature request, I think I can reframe it slightly differently. It's not that you want "optional fallback" since that wouldn't make sense for new screens (we've got to show something). What I believe you're looking for is a way to skip showing the fallback if the content is already in HTML. This is precisely how React behaves in Concurrent Mode so the feature request is already implemented (and will eventually become the default behavior in a stable release).

对我来说,等待不是问题,所以目前我将省略 lazy-loading 路线,因为这涉及 hobby-project,我有时间等待未来的发布。

根据我的经验(使用 React 17),如果将 null 传递给后备参数,则不会发生闪烁。

我有一个呈现惰性组件的模态组件。

这是我的 Typescript 解决方案:

type LazyLoadHOC = {
   component: React.LazyExoticComponent<any>,
   fallback?: React.ComponentType | null,
   [x:string]: any
};

export const LazyLoad: React.FC<LazyLoadHOC> = ({
     component: Component, fallback = null, ...props
}) => {
  return (
    <React.Suspense fallback={fallback}>
        <Component {...props} />
    </React.Suspense>
  );
};

这是我的模态框:

const AddressFormModel = React.lazy(() => import('@components/address/address-form-modal'));

<Modal show={isOpen} backdrop={'static'} dialogClassName='custom-modal'>
    <ModalBody>
       {view === 'ADDRESS-FORM' && <LazyLoad component={AddressFormModel} />}
    </ModalBody>
</Modal>

这将确保不会触发您的全局 React.Suspense。