有没有办法检查延迟加载的组件(使用 React.Lazy)是否已完成加载?

Jan*_*Jan 5 javascript reactjs react-hooks react-suspense react-lazy-load

我正在开发一个应用程序,如果下一页有任何尚未加载的延迟加载组件,我们希望在页面之间进行转换。所以我想弄清楚是否有任何方法可以可靠地检查延迟加载的组件是否已完成加载。

此解决方案有效,但在延迟加载的组件第一次尝试加载时才有效——即如果它立即呈现则无效,因为延迟加载的组件已经加载。

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 <></>
}
Run Code Online (Sandbox Code Playgroud)

此组件调用正确onLoadonComplete第一次它的加载。然而,在随后的时间里,因为延迟加载的组件现在被缓存,子组件会立即呈现,onLoad并且onComplete永远不会呈现回退,这意味着永远不会被调用。

我尝试过的一件事是将第二个Trigger放在 的主体中SuspenseTrigger

function ensureLoadCompleteCalled() {
  onLoad()
  onComplete()
}

return (
  <React.Suspense fallback={/* same as before */}>
    {props.children}
    <Trigger onLoad={ensureLoadCompleteCalled} />
  </React.Suspense>
)
Run Code Online (Sandbox Code Playgroud)

这不起作用,因为Suspense即使其他元素没有完全加载,子元素也会立即呈现。所以,onLoadonComplete立刻被调用,不管是否悬念完成加载与否。

为了解决这个问题,我还尝试了一些更高级的状态检查(PasteBin 上的代码)。主要的困难是检查是否已呈现回退,我无法弄清楚如何可靠地做到这一点。我试过在检查之前等待 100 毫秒,但由于某种原因,即使这样也不能可靠地工作。也许有可能useRef

有任何想法吗?

小智 2

您是否尝试将您的组件包装{props.children}在 Loader 功能组件上,以便在 useLayoutEffect 上执行 onComplete 函数?

这只是一个原始想法,但它可能有效......

const Loader = ({ onLoad, onComplete, children }) => {
  if (onLoad) {
    onLoad();
  }

  useLayoutEffect(() => {
    if (onComplete) {
      onComplete();
    }
  }, []);

  return children;
}
Run Code Online (Sandbox Code Playgroud)
<React.Suspense fallback={/* same as before */}>
    <Loader onLoad={onLoad} onComplete={onComplete}>
      {props.children}
    </Loader>
</React.Suspense>
Run Code Online (Sandbox Code Playgroud)