如何延迟加载 React "widget"?



我的术语在这里可能是错误的,但我不知道该怎么称呼它,除了一个" widget ";当你没有一个完整的React应用程序,但是在一个静态的HTML页面上附加了一小部分React到不同的root时。但是,这就是我正在做的:

const StripeForm = React.lazy(() => import('./Stripeform'));
// ...
const formPlaceholder = document.getElementById('cwr-stripe-form');
const formRoot = createRoot(formPlaceholder);
formRoot.render(
<React.StrictMode>
<StripeForm />
</React.StrictMode>
);

我想解决的问题是,我想延迟加载我的StripeForm,这样它就不会加载,直到需要(因此可能永远不会)。

我有React.lazyimport和我的webpack包工作良好。问题是"直到需要的时候"。

据我所知,惰性加载组件在开始渲染时加载,我想通常是在它们移动到视窗时加载。我同样认为,"通常"被我调用.render的事实所覆盖,我猜这会导致它立即渲染。

这些猜测可能是错误的,但事实是,当我加载我的网页时,所谓的惰性加载组件被加载,即使它不在视窗中。

如何获得这些"小工具"(页面上还有其他几个)加载惰性(即,附加到我的root占位符元素,但实际上没有加载和渲染,直到必要)?

你已经使用了lazy,所以React只会在没有渲染的情况下导入组件。问题是,默认情况下,你仍然在渲染组件,所以一旦组件可用,它仍然会被加载。

React是声明式的,所以解决这个问题的方法是只有当你想要呈现组件时才有条件地呈现它。您可以通过使用诸如react-is-visible这样的可见性库来实现这一点,例如:

import React, { useRef } from 'react'
import { useIsVisible } from 'react-is-visible'
function LazyStripeForm() {
const ref = useRef()
const isVisible = useIsVisible(ref, { once: true })
return <div ref={ref}>{isVisible && <StripeForm />}</div>
}

现在你可以渲染LazyStripeForm而不是StripeForm,它应该做你想要的。

同样,如果StripeForm有很多依赖项,你应该确保你的构建工具是代码分割文件,这样它就不会不必要地增加你的主包的大小。

最新更新