首页 > 解决方案 > 嵌套中一致的后备加载动画成分

问题描述

我有一个带有一系列嵌套<Suspense>组件的 React 版本 17 应用程序。每个都使用相同的<Loader>组件,其中包含一个 CSS 动画微调器:

<App>
  <Suspense fallback={<Loader/>}>
    <OuterWrapper>
      <Suspense fallback={<Loader/>}>
        <InnerWrapper>
          {content}
        </InnerWrapper>
      </Suspense>
    </OuterWrapper>
  </Suspense>
</App>

当外部<Suspense>组件完成加载并交换<Loader><OuterWrapper>然后开始加载内部组件时,将在 DOM 中加载<Suspense>该组件的新实例。<Loader>正因为如此,动画在其动画循环开始时重新开始,这使得微调器看起来“卡顿”。

我尝试过 wrapping <Loader>React.memo()但这并没有帮助,因为<Loader>组件的同一个实例实际上并没有被重新渲染,而是在 DOM 中被内部<Suspense>组件替换为全新的实例。我认为我需要在 DOM 中保持呈现相同的实例,以便动画看起来流畅。

解决这个问题的好方法是什么?我知道 React 版本 18 的实验性并发模式功能可以帮助解决这个问题,但我无法在这个应用程序中使用 React 的 alpha/beta 版本。

标签: javascriptreactjsloadingreact-suspense

解决方案


我认为<Suspense>在 React 17 中没有解决这个问题的好方法,所以我将<Loader>组件移到了它自己的提供程序中,该提供程序包装了其他所有内容。一旦最后一个嵌套组件完成加载,它使用 React Context 将加载动画换成应用内容。

在这个方案中, fallbackprops<Suspense>被更改为。null

<LoaderProvider loader={<Loader />}>
  <App>
    <Suspense fallback={null}>
      <OuterWrapper>
        <Suspense fallback={null}>
          <InnerWrapper>
            {content}
          </InnerWrapper>
        </Suspense>
      </OuterWrapper>
    </Suspense>
  </App>
</LoaderProvider>

推荐阅读