fixed unfound node error when Suspense is filtered (#20019)

* fixed unfound node error when Suspense is filtered

* added a test for filtered Suspense node
This commit is contained in:
IDrissAitHafid
2020-10-15 14:45:23 -04:00
committed by GitHub
parent c57fe4a2c1
commit 2eb3181eb4
3 changed files with 31 additions and 1 deletions
@@ -97,6 +97,13 @@ exports[`Store component filters should not break when Suspense nodes are filter
<Component>
`;
exports[`Store component filters should not break when Suspense nodes are filtered from the tree: 3: suspended 1`] = `
[root]
▾ <Wrapper>
▾ <Loading>
<div>
`;
exports[`Store component filters should support filtering by element type: 1: mount 1`] = `
[root]
▾ <Root>
@@ -256,5 +256,8 @@ describe('Store component filters', () => {
act(() => ReactDOM.render(<Wrapper shouldSuspend={false} />, container));
expect(store).toMatchSnapshot('2: resolved');
act(() => ReactDOM.render(<Wrapper shouldSuspend={true} />, container));
expect(store).toMatchSnapshot('3: suspended');
});
});
+21 -1
View File
@@ -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,
);