From 6fe78f4203e88e000188778a5aaa9f5f55fd1f0a Mon Sep 17 00:00:00 2001 From: idango10 <75563024+idango10@users.noreply.github.com> Date: Tue, 29 Aug 2023 18:42:35 +0300 Subject: [PATCH] fix: devtools source field disappears after component remount (#27297) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary Fixes: https://github.com/facebook/react/issues/27296 On actions that cause a component to change its signature, and therefore to remount, the `_debugSource` property of the fiber updates in delay and causes the `devtools` source field to vanish. This issue happens in https://github.com/facebook/react/blob/main/packages/react-reconciler/src/ReactFiberBeginWork.js ```js function beginWork( current: Fiber | null, workInProgress: Fiber, renderLanes: Lanes, ): Fiber | null { if (__DEV__) { if (workInProgress._debugNeedsRemount && current !== null) { // This will restart the begin phase with a new fiber. return remountFiber( current, workInProgress, createFiberFromTypeAndProps( workInProgress.type, workInProgress.key, workInProgress.pendingProps, workInProgress._debugOwner || null, workInProgress.mode, workInProgress.lanes, ), ); } } // ... ``` `remountFiber` uses the 3rd parameter as the new fiber (`createFiberFromTypeAndProps(...)`), but this parameter doesn’t contain a `_debugSource`. ## How did you test this change? Tested by monkey patching `./node_modules/react-dom/cjs/react-dom.development.js`: image https://github.com/facebook/react/assets/75563024/0650ae5c-b277-44d1-acbb-a08d98bd38e0 --- packages/react-reconciler/src/ReactFiber.js | 7 ++++++- packages/react-reconciler/src/ReactFiberBeginWork.js | 2 ++ packages/react-reconciler/src/ReactFiberCommitWork.js | 1 + 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/packages/react-reconciler/src/ReactFiber.js b/packages/react-reconciler/src/ReactFiber.js index 1eb339328d940..c9af059d20de6 100644 --- a/packages/react-reconciler/src/ReactFiber.js +++ b/packages/react-reconciler/src/ReactFiber.js @@ -7,7 +7,7 @@ * @flow */ -import type {ReactElement} from 'shared/ReactElementType'; +import type {ReactElement, Source} from 'shared/ReactElementType'; import type {ReactFragment, ReactPortal, ReactScope} from 'shared/ReactTypes'; import type {Fiber} from './ReactInternalTypes'; import type {RootTag} from './ReactRootTags'; @@ -490,6 +490,7 @@ export function createFiberFromTypeAndProps( type: any, // React$ElementType key: null | string, pendingProps: any, + source: null | Source, owner: null | Fiber, mode: TypeOfMode, lanes: Lanes, @@ -643,6 +644,7 @@ export function createFiberFromTypeAndProps( fiber.lanes = lanes; if (__DEV__) { + fiber._debugSource = source; fiber._debugOwner = owner; } @@ -654,8 +656,10 @@ export function createFiberFromElement( mode: TypeOfMode, lanes: Lanes, ): Fiber { + let source = null; let owner = null; if (__DEV__) { + source = element._source; owner = element._owner; } const type = element.type; @@ -665,6 +669,7 @@ export function createFiberFromElement( type, key, pendingProps, + source, owner, mode, lanes, diff --git a/packages/react-reconciler/src/ReactFiberBeginWork.js b/packages/react-reconciler/src/ReactFiberBeginWork.js index e2024c8bf6f22..612d8bb2c7f2e 100644 --- a/packages/react-reconciler/src/ReactFiberBeginWork.js +++ b/packages/react-reconciler/src/ReactFiberBeginWork.js @@ -531,6 +531,7 @@ function updateMemoComponent( Component.type, null, nextProps, + null, workInProgress, workInProgress.mode, renderLanes, @@ -4014,6 +4015,7 @@ function beginWork( workInProgress.type, workInProgress.key, workInProgress.pendingProps, + workInProgress._debugSource || null, workInProgress._debugOwner || null, workInProgress.mode, workInProgress.lanes, diff --git a/packages/react-reconciler/src/ReactFiberCommitWork.js b/packages/react-reconciler/src/ReactFiberCommitWork.js index ef1a97815a653..93cd97e8adb01 100644 --- a/packages/react-reconciler/src/ReactFiberCommitWork.js +++ b/packages/react-reconciler/src/ReactFiberCommitWork.js @@ -1697,6 +1697,7 @@ function detachFiberAfterEffects(fiber: Fiber) { fiber.stateNode = null; if (__DEV__) { + fiber._debugSource = null; fiber._debugOwner = null; }