Fiber节点的EffectTag 为什么要用二进制表示?

559 阅读2分钟

几种EffectTag

export const NoFlags = /*                      */ 0b0000000000000000000;
export const PerformedWork = /*                */ 0b0000000000000000001;

export const Placement = /*                    */ 0b0000000000000000010;
export const Update = /*                       */ 0b0000000000000000100;
export const PlacementAndUpdate = /*           */ 0b0000000000000000110;
export const Deletion = /*                     */ 0b0000000000000001000;
export const ContentReset = /*                 */ 0b0000000000000010000;
export const Callback = /*                     */ 0b0000000000000100000;
export const DidCapture = /*                   */ 0b0000000000001000000;
export const Ref = /*                          */ 0b0000000000010000000;
export const Snapshot = /*                     */ 0b0000000000100000000;
export const Passive = /*                      */ 0b0000000001000000000;
export const Hydrating = /*                    */ 0b0000000010000000000;
export const HydratingAndUpdate = /*           */ 0b0000000010000000100;
export const Visibility = /*                   */ 0b0000000100000000000;

为什么要用二进制?

考虑一种情况,一个Fiber节点对应的DOM节点,首先插入页面,其次需要更新属性, 使用按位或操作可以很轻松的做到

    let flag = NoFlags
    flag |= Placement
    flag |= Update
    // ...
    
    flag === PlacementAndUpdate // true

在源码中commitMutationEffects方法就用到了EffectTag

const primaryFlags = flags & (Placement | Update | Deletion | Hydrating);
    switch (primaryFlags) {
      case Placement: ...
      case PlacementAndUpdate: ...
      case Hydrating: ...
      case HydratingAndUpdate: ...
      case Update: ...
      case Deletion: ...
    }

(Placement | Update | Deletion | Hydrating)几个tags按位或操作得到二进制数0b0000010000001110,包含了switch的所有情况,而可以造成突变的几种情况都被包含在内