最近在看这篇文章,从文章中了解到在Fiber节点中,与Fiber节点关联的effects,被编码在节点的effectTag字段之中。但是一个组件可能有多个副作用,那么React是如何通过一个字段判断要执行多个副作用的呢?
React使用了按位或构造了一个属性集, 比如:
0b00000000100
,表示需要执行componentDidUpdate副作用0b00100000000
, 表示需要执行getSnapshotBeforeUpdate副作用
effectTag默认值是0。在updateClassInstance中,使用按位或添加副作用的标识
if (typeof instance.componentDidUpdate === 'function') {
workInProgress.effectTag |= Update;
}
if (typeof instance.getSnapshotBeforeUpdate === 'function') {
workInProgress.effectTag |= Snapshot;
}
比如我们的组件同时拥有Update副作用和Snapshot副作用,那么Fiber节点的effectTag就是
effectTag |= 0b00000000100
effectTag |= 0b00100000000
此时effectTag的二进制表示就是0b00100000100
, 第3位等于1,第9位等于1。
在commitAllLifeCycles中,通过按位与判断是否需要对应的副作用
function commitAllLifeCycles(finishedRoot, ...) {
while (nextEffect !== null) {
const effectTag = nextEffect.effectTag;
if (effectTag & (Update | Callback)) {
const current = nextEffect.alternate;
commitLifeCycles(finishedRoot, current, nextEffect, ...);
}
nextEffect = nextEffect.nextEffect;
}
}
比如我们的effectTag是0b00100000100
, 我们需要检查第三位是否设置为1,我们使用按位与判断
0b00100000100 & 0b00000100100 // 不等于0
0b00100000000 & 0b00000100100 // 等于0
按位与的规则是:1 & 1 等于 1; 1 & 0 等于 0;0 & 1 等于0;0 & 0等于0。如果第3位不是1,按位与就会得到0。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。