认识
一、认识
<Suspense>
允许在子组件完成加载前展示后备方案。<Suspense>
可以与以下组合使用:
-
lazy
组件 -
transition fallback
-
use
-
Offscreen
-
Selective Hydration
-
RSC
1.1 架构
Suspense
架构:
-
正常状态:
<Suspense>
渲染子孙组件 -
挂起状态:
<Suspense>
渲染fallback
其中, 造成挂起状态的原因有很多, 比如:
-
<Cpn />
或者子孙组件是懒加载组件 -
<Cpn />
或者子孙组件触发并发更新 -
<Cpn />
或者子孙是Selective Hydration
-
<Cpn />
或者子孙组件使用use
请求数据
1.2 思想
Suspense
的实现有两种思路:
-
只有一个
Child
:Pending
流程child
指向fallback
, 正常流程指向children
。这样的实现有两个缺点:-
无法保存
children
对应状态 -
切换后
children
对应DOM
需要完全销毁
-
-
有两个
Child
:beginWork
时,Suspense.child
始终指向Offscreen
对应children
,Suspense.child.sibling
指向Fragment
对应fallback
。通过改变Offscreen
的mode
值来改变显示与隐藏,Offscreen
子树不会解除绑定,Offscreen
中的状态得以保留。因此,React
采用的是这种思路。
二、工作流程
Suspense
工作流程如下:
-
beginWork
时进入以下任意流程:-
mount
时正常流程 -
update
时正常流程 -
mount
时挂起流程 -
update
时挂起流程
-
-
completeWork
时对比current Offscreen mode
与workInProgress Offscreen mode
, 如果发现下述情况, 则标记Visibility EffectTag
:-
mode
从hidden
变为visible
-
mode
从visible
变为hidden
-
current === null && hidden
-
-
commitWork
时处理Visibility EffectTag
, 处理Visibility EffectTag
时需要找到所有子树顶层Host
节点
三、触发流程
3.1 use
-
正常流程对应
render
阶段 -
遇到
use
,use
手动抛出SuspenseException
错误, 进入Suspense
挂起流程 -
进入
Suspense
挂起流程对应render
阶段 -
进入
Suspense
挂起流程commit
阶段,渲染fallback
对应的Loading
组件 -
请求返回后,进入正常流程对应的
render
阶段 -
进入正常流程对应的
commit
阶段, 渲染Suspense
对应的Children