有没有办法检查延迟加载的组件(使用 React.Lazy)是不是已完成加载?
Posted
技术标签:
【中文标题】有没有办法检查延迟加载的组件(使用 React.Lazy)是不是已完成加载?【英文标题】:Is there a way to check if a lazy-loaded component (with React.Lazy) has finished loading?有没有办法检查延迟加载的组件(使用 React.Lazy)是否已完成加载? 【发布时间】: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 />
【参考方案1】:
检查_status
会起作用吗?
const Uninitialized = -1;
const Pending = 0;
const Resolved = 1;
const Rejected = 2;
见https://github.com/facebook/react/blob/master/packages/react/src/ReactLazy.js
【讨论】:
【参考方案2】:您是否尝试将您的 props.children
包装在加载器功能组件上,然后使用布局效果执行 onComplete 功能?
这只是一个原始的想法,但它可能会起作用......
const Loader = ( onLoad, onComplete, children ) =>
if (onLoad)
onLoad();
useLayoutEffect(() =>
if (onComplete)
onComplete();
, []);
return children;
<React.Suspense fallback=/* same as before */>
<Loader onLoad=onLoad onComplete=onComplete>
props.children
</Loader>
</React.Suspense>
【讨论】:
我不断收到此警告:在渲染不同组件 (Loader
) 时无法更新组件 (BaseRoutes
)。要在 Loader
中找到错误的 setState() 调用,请按照 Switch (at BaseRoutes.js:74) 中 Suspense (at BaseRoutes.js:80) 中的 Loader (at BaseRoutes.js:81) 中所述的堆栈跟踪在 BaseRoutes(在 Layout.js:55) 在 Layout(在 App.js:21) 在 Router(由 BrowserRouter 创建) 在 BrowserRouter(在 App.js:20) 在 App(在 src/index.js:55)
以上是关于有没有办法检查延迟加载的组件(使用 React.Lazy)是不是已完成加载?的主要内容,如果未能解决你的问题,请参考以下文章