When resetting Suspense children, use the fallback child set if needed
This fixes the bug I introduced in the previous refactor which Suspense test caught.
Dan Abramov committed
Apr 16, 2019 at 16:45 UTC
f4e223bcebdbda8a4c9ce4782fb1dc2538715274
1 file changed
+11
-3
src/backend/renderer.js
+11
-3
@@ -861,7 +861,7 @@ export function attach(
861
}
862
}
863
864
- function recordResetChildren(fiber: Fiber) {
864
+ function recordResetChildren(fiber: Fiber, childSet: Fiber) {
865
// The frontend only really cares about the displayName, key, and children.
866
// The first two don't really change, so we are only concerned with the order of children here.
867
// This is trickier than a simple comparison though, since certain types of fibers are filtered.
@@ -869,7 +869,7 @@ export function attach(
869
870
// This is a naive implimentation that shallowly recurses children.
871
// We might want to revisit this if it proves to be too inefficient.
872
- let child = fiber.child;
872
+ let child = childSet;
873
while (child !== null) {
874
findReorderedChildrenRecursively(child, nextChildren);
875
child = child.sibling;
@@ -1023,8 +1023,16 @@ export function attach(
1023
}
1024
}
1025
if (shouldResetChildren) {
1026
+ // We need to crawl the subtree for closest non-filtered Fibers
1027
+ // so that we can display them in a flat children set.
1028
if (shouldIncludeInTree) {
1027
- recordResetChildren(nextFiber);
1029
+ // Normally, search for children from the rendered child.
1030
+ let nextChildSet = nextFiber.child;
1031
+ if (nextDidTimeOut) {
1032
+ // Special case: timed-out Suspense renders the fallback set.
1033
+ nextChildSet = nextFiber.child.sibling;
1034
+ }
1035
+ recordResetChildren(nextFiber, nextChildSet);
1036
// We've handled the child order change for this Fiber.
1037
// Since it's included, there's no need to invalidate parent child order.
1038
return false;