Skip to content

Commit

Permalink
[DevTools] bug fix for Hydrating fibers (#25663)
Browse files Browse the repository at this point in the history
## 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
  • Loading branch information
mondaychen committed Nov 11, 2022
1 parent d1e35c7 commit c54e354
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 32 deletions.
17 changes: 17 additions & 0 deletions packages/react-devtools-shared/src/backend/ReactFiberFlags.js
Original file line number Diff line number Diff line change
@@ -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;
35 changes: 7 additions & 28 deletions packages/react-devtools-shared/src/backend/renderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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;
Expand All @@ -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.
Expand Down Expand Up @@ -562,7 +550,6 @@ export function getInternalReactConstants(
getTypeSymbol,
ReactPriorityLevels,
ReactTypeOfWork,
ReactTypeOfSideEffect,
StrictModeBits,
};
}
Expand Down Expand Up @@ -595,16 +582,8 @@ export function attach(
getTypeSymbol,
ReactPriorityLevels,
ReactTypeOfWork,
ReactTypeOfSideEffect,
StrictModeBits,
} = getInternalReactConstants(version);
const {
DidCapture,
Hydrating,
NoFlags,
PerformedWork,
Placement,
} = ReactTypeOfSideEffect;
const {
CacheComponent,
ClassComponent,
Expand Down
8 changes: 4 additions & 4 deletions packages/react-reconciler/src/ReactFiberFlags.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down

0 comments on commit c54e354

Please sign in to comment.