嵌套 <Suspense> 组件中一致的后备加载动画

Posted

技术标签:

【中文标题】嵌套 <Suspense> 组件中一致的后备加载动画【英文标题】:Consistent fallback loading animation in nested <Suspense> components 【发布时间】:2021-10-09 03:27:02 【问题描述】:

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

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

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

我曾尝试将&lt;Loader&gt; 包装在React.memo() 中,但这无济于事,因为&lt;Loader&gt; 组件的同一个实例实际上并没有被重新渲染,而是在DOM 中被一个全新的替换内部&lt;Suspense&gt; 组件的实例。我认为我需要在 DOM 中保持呈现相同的实例,以便动画看起来流畅。

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

【问题讨论】:

【参考方案1】:

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

在此方案中,&lt;Suspense&gt;fallback 属性更改为 null

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

【讨论】:

以上是关于嵌套 <Suspense> 组件中一致的后备加载动画的主要内容,如果未能解决你的问题,请参考以下文章

vue3中的Suspense(不确定的)

react懒加载(lazy, Suspense)

react懒加载(lazy, Suspense)

683 vue3的动态组件,keep-alive,缓存组件的生命周期,异步组件和Suspense,$refs,$parent和$root,生命周期,组件的v-model

react懒加载(lazy, Suspense)

React Suspense 延迟加载没有回退