【发布时间】:2020-10-15 06:59:59
【问题描述】:
我正在开发一个应用程序,如果下一页有任何尚未加载的延迟加载组件,我们希望延迟页面之间的转换。所以我想弄清楚是否有任何方法可以可靠地检查延迟加载的组件是否已经完成加载。
此解决方案有效,但仅在延迟加载的组件第一次尝试加载时 - 即如果它立即呈现,因为延迟加载的组件已经加载。
import React, {PropsWithChildren, useEffect} from 'react'
export default function SuspenseTrigger(props) {
return (
<React.Suspense fallback={
<>
{props.fallback}
<Trigger onLoad={props.onLoad} onComplete={props.onComplete} />
</>
}>
{props.children}
</React.Suspense>
)
}
function Trigger(props) {
useEffect(() => {
if (props.onLoad) {
props.onLoad()
}
return () => {
if (props.onComplete) {
setTimeout(props.onComplete)
}
}
}, [])
return <></>
}
此组件在第一次加载时正确调用onLoad 和onComplete。但是,在随后的时间里,由于延迟加载的组件现在被缓存,子组件会立即呈现,并且 永远不会呈现回退,这意味着永远不会调用 onLoad 和 onComplete。 p>
我尝试过的一件事是在 SuspenseTrigger 的正文中添加第二个 Trigger:
function ensureLoadCompleteCalled() {
onLoad()
onComplete()
}
return (
<React.Suspense fallback={/* same as before */}>
{props.children}
<Trigger onLoad={ensureLoadCompleteCalled} />
</React.Suspense>
)
这是行不通的,因为 Suspense 的子元素会立即渲染,即使其他元素没有完全加载。 所以onLoad 和 onComplete 会立即被调用,无论是否Suspense 是否已加载完毕。
为了解决这个问题,我还尝试了一些更高级的状态检查(code on PasteBin)。主要的困难是检查后备是否已经呈现,我无法弄清楚如何可靠地做到这一点。我试过在检查之前等待 100 毫秒,但由于某种原因,即使这样也不能可靠地工作。 useRef 或许可以?
有什么想法吗?
【问题讨论】:
-
您能像这样为孩子添加第二个触发器吗?
{props.children}<Trigger onLoad={props.onComplete} />
标签: javascript reactjs react-hooks react-suspense react-lazy-load