From 18d8fc965a5e4d2157fa8318878078adb8c61aa5 Mon Sep 17 00:00:00 2001 From: IDrissAitHafid <31975500+IDrissAitHafid@users.noreply.github.com> Date: Thu, 15 Oct 2020 19:45:23 +0100 Subject: [PATCH] fixed unfound node error when Suspense is filtered (#20019) * fixed unfound node error when Suspense is filtered * added a test for filtered Suspense node --- .../storeComponentFilters-test.js.snap | 7 ++++++ .../__tests__/storeComponentFilters-test.js | 3 +++ .../src/backend/renderer.js | 22 ++++++++++++++++++- 3 files changed, 31 insertions(+), 1 deletion(-) diff --git a/packages/react-devtools-shared/src/__tests__/__snapshots__/storeComponentFilters-test.js.snap b/packages/react-devtools-shared/src/__tests__/__snapshots__/storeComponentFilters-test.js.snap index cfe68aa69ecbc..49035b9927836 100644 --- a/packages/react-devtools-shared/src/__tests__/__snapshots__/storeComponentFilters-test.js.snap +++ b/packages/react-devtools-shared/src/__tests__/__snapshots__/storeComponentFilters-test.js.snap @@ -97,6 +97,13 @@ exports[`Store component filters should not break when Suspense nodes are filter `; +exports[`Store component filters should not break when Suspense nodes are filtered from the tree: 3: suspended 1`] = ` +[root] + ▾ + ▾ +
+`; + exports[`Store component filters should support filtering by element type: 1: mount 1`] = ` [root] ▾ diff --git a/packages/react-devtools-shared/src/__tests__/storeComponentFilters-test.js b/packages/react-devtools-shared/src/__tests__/storeComponentFilters-test.js index bfbf3e98210a9..a8a0e151ef748 100644 --- a/packages/react-devtools-shared/src/__tests__/storeComponentFilters-test.js +++ b/packages/react-devtools-shared/src/__tests__/storeComponentFilters-test.js @@ -256,5 +256,8 @@ describe('Store component filters', () => { act(() => ReactDOM.render(, container)); expect(store).toMatchSnapshot('2: resolved'); + + act(() => ReactDOM.render(, container)); + expect(store).toMatchSnapshot('3: suspended'); }); }); diff --git a/packages/react-devtools-shared/src/backend/renderer.js b/packages/react-devtools-shared/src/backend/renderer.js index c10d71bbfec2e..23deda7dde258 100644 --- a/packages/react-devtools-shared/src/backend/renderer.js +++ b/packages/react-devtools-shared/src/backend/renderer.js @@ -1437,6 +1437,9 @@ export function attach( } function recordResetChildren(fiber: Fiber, childSet: Fiber) { + if (__DEBUG__) { + debug('recordResetChildren()', childSet, fiber); + } // The frontend only really cares about the displayName, key, and children. // The first two don't really change, so we are only concerned with the order of children here. // This is trickier than a simple comparison though, since certain types of fibers are filtered. @@ -1471,6 +1474,23 @@ export function attach( nextChildren.push(getFiberID(getPrimaryFiber(fiber))); } else { let child = fiber.child; + const isTimedOutSuspense = + fiber.tag === SuspenseComponent && fiber.memoizedState !== null; + if (isTimedOutSuspense) { + // Special case: if Suspense mounts in a timed-out state, + // get the fallback child from the inner fragment, + // and skip over the primary child. + const primaryChildFragment = fiber.child; + const fallbackChildFragment = primaryChildFragment + ? primaryChildFragment.sibling + : null; + const fallbackChild = fallbackChildFragment + ? fallbackChildFragment.child + : null; + if (fallbackChild !== null) { + child = fallbackChild; + } + } while (child !== null) { findReorderedChildrenRecursively(child, nextChildren); child = child.sibling; @@ -1592,7 +1612,7 @@ export function attach( if (nextFallbackChildSet != null) { mountFiberRecursively( nextFallbackChildSet, - nextFiber, + shouldIncludeInTree ? nextFiber : parentFiber, true, traceNearestHostComponentUpdate, );