[DevTools] bug fix for Hydrating fibers (#25663)

## Summary

This PR is to fix a bug: an "element cannot be found" error when
hydrating Server Components

### The problem
<img width="1061" alt="image"
src="https://user-images.githubusercontent.com/1001890/201206046-ac32a5e3-b08a-4dc2-99f4-221dad504b28.png">

To reproduce:
1. setting up a vercel next.js 13 playground locally
https://github.com/vercel/app-playground
2. visit http://localhost:3000/loading
3. click "electronics" button to navigate to
http://localhost:3000/loading/electronics to trigger hydrating
4. inspect one of the skeleton card UI from React DevTools extension

### The root cause & fix
This bug was introduced in #22527. When syncing reconciler changes, the
value of `Hydrating` was copied from another variable `Visibility` (one
more zero in the binary number).
To avoid this kind of issue in the future, a new file `ReactFiberFlags`
is created following the same format of the one in reconciler, so that
it's easier to sync the number without making mistakes.
The reconciler fiber flag file is also updated to reflect which of the
flags are used in devtools

## How did you test this change?

I build it locally and the bug no longer exist on
http://localhost:3000/loading
This commit is contained in:
Mengdi Chen
2022-11-11 15:18:06 -05:00
committed by GitHub
parent d1e35c7039
commit c54e3541b2
3 changed files with 28 additions and 32 deletions

View File

@@ -0,0 +1,17 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
*/
// This list of flags must be synced with the following file:
// https://github.com/facebook/react/blob/main/packages/react-reconciler/src/ReactFiberFlags.js
export const NoFlags = /* */ 0b00000000000000000000000000;
export const PerformedWork = /* */ 0b00000000000000000000000001;
export const Placement = /* */ 0b00000000000000000000000010;
export const DidCapture = /* */ 0b00000000000000000001000000;
export const Hydrating = /* */ 0b00000000000000100000000000;

View File

@@ -88,6 +88,13 @@ import {
MEMO_SYMBOL_STRING,
SERVER_CONTEXT_SYMBOL_STRING,
} from './ReactSymbols';
import {
DidCapture,
NoFlags,
PerformedWork,
Placement,
Hydrating,
} from './ReactFiberFlags';
import {format} from './utils';
import {
enableProfilerChangedHookIndices,
@@ -135,15 +142,6 @@ type ReactPriorityLevelsType = {
NoPriority: number,
};
type ReactTypeOfSideEffectType = {
DidCapture: number,
NoFlags: number,
PerformedWork: number,
Placement: number,
Incomplete: number,
Hydrating: number,
};
function getFiberFlags(fiber: Fiber): number {
// The name of this field changed from "effectTag" to "flags"
return fiber.flags !== undefined ? fiber.flags : (fiber: any).effectTag;
@@ -162,19 +160,9 @@ export function getInternalReactConstants(
getDisplayNameForFiber: getDisplayNameForFiberType,
getTypeSymbol: getTypeSymbolType,
ReactPriorityLevels: ReactPriorityLevelsType,
ReactTypeOfSideEffect: ReactTypeOfSideEffectType,
ReactTypeOfWork: WorkTagMap,
StrictModeBits: number,
} {
const ReactTypeOfSideEffect: ReactTypeOfSideEffectType = {
DidCapture: 0b10000000,
NoFlags: 0b00,
PerformedWork: 0b01,
Placement: 0b10,
Incomplete: 0b10000000000000,
Hydrating: 0b1000000000000,
};
// **********************************************************
// The section below is copied from files in React repo.
// Keep it in sync, and add version guards if it changes.
@@ -562,7 +550,6 @@ export function getInternalReactConstants(
getTypeSymbol,
ReactPriorityLevels,
ReactTypeOfWork,
ReactTypeOfSideEffect,
StrictModeBits,
};
}
@@ -595,16 +582,8 @@ export function attach(
getTypeSymbol,
ReactPriorityLevels,
ReactTypeOfWork,
ReactTypeOfSideEffect,
StrictModeBits,
} = getInternalReactConstants(version);
const {
DidCapture,
Hydrating,
NoFlags,
PerformedWork,
Placement,
} = ReactTypeOfSideEffect;
const {
CacheComponent,
ClassComponent,

View File

@@ -11,22 +11,22 @@ import {enableCreateEventHandleAPI} from 'shared/ReactFeatureFlags';
export type Flags = number;
// Don't change these two values. They're used by React Dev Tools.
// Don't change these values. They're used by React Dev Tools.
export const NoFlags = /* */ 0b00000000000000000000000000;
export const PerformedWork = /* */ 0b00000000000000000000000001;
export const Placement = /* */ 0b00000000000000000000000010;
export const DidCapture = /* */ 0b00000000000000000001000000;
export const Hydrating = /* */ 0b00000000000000100000000000;
// You can change the rest (and add more).
export const Placement = /* */ 0b00000000000000000000000010;
export const Update = /* */ 0b00000000000000000000000100;
export const ChildDeletion = /* */ 0b00000000000000000000001000;
export const ContentReset = /* */ 0b00000000000000000000010000;
export const Callback = /* */ 0b00000000000000000000100000;
export const DidCapture = /* */ 0b00000000000000000001000000;
export const ForceClientRender = /* */ 0b00000000000000000010000000;
export const Ref = /* */ 0b00000000000000000100000000;
export const Snapshot = /* */ 0b00000000000000001000000000;
export const Passive = /* */ 0b00000000000000010000000000;
export const Hydrating = /* */ 0b00000000000000100000000000;
export const Visibility = /* */ 0b00000000000001000000000000;
export const StoreConsistency = /* */ 0b00000000000010000000000000;