Alternate fix for #14198
This doesn't rely on checking the tag. When the alternate of a parent is missing, it assumes it's a fragment indirection and moves onto the next parent fiber.
Andrew Clark committed
Apr 3, 2019 at 15:07 UTC
43b1f74c88d986c88623412be7b1d65a6e271779
1 file changed
+18
-26
packages/react-reconciler/src/ReactFiberTreeReflection.js
+18
-26
@@ -21,8 +21,6 @@ import {
21
HostRoot,
22
HostPortal,
23
HostText,
24
- Fragment,
25
- SuspenseComponent,
24
} from 'shared/ReactWorkTags';
25
import {NoEffect, Placement} from 'shared/ReactSideEffectTags';
26
@@ -115,33 +113,27 @@ export function findCurrentFiberUsingSlowPath(fiber: Fiber): Fiber | null {
113
// If we have two possible branches, we'll walk backwards up to the root
114
// to see what path the root points to. On the way we may hit one of the
115
// special cases and we'll deal with them.
118
- let a = fiber;
119
- let b = alternate;
116
+ let a: Fiber = fiber;
117
+ let b: Fiber = alternate;
118
while (true) {
119
let parentA = a.return;
122
- let parentB = parentA ? parentA.alternate : null;
123
- if (!parentA || !parentB) {
124
- // We're either at the root, or we're in a special Fragment
125
- // with no alternate, which is how Suspense (un)hiding works.
126
- let maybeSuspenseFragment = parentA || parentB;
127
- if (maybeSuspenseFragment && maybeSuspenseFragment.tag === Fragment) {
128
- const maybeSuspense = maybeSuspenseFragment.return;
129
- if (
130
- maybeSuspense &&
131
- maybeSuspense.tag === SuspenseComponent &&
132
- // If state isn't null, it timed out and we have two Fragment children.
133
- maybeSuspense.memoizedState !== null
134
- ) {
135
- parentA = maybeSuspense;
136
- parentB = maybeSuspense;
137
- a = maybeSuspenseFragment;
138
- b = maybeSuspenseFragment;
139
- } else {
140
- break;
141
- }
142
- } else {
143
- break;
120
+ if (parentA === null) {
121
+ // We're at the root.
122
+ break;
123
+ }
124
+ let parentB = parentA.alternate;
125
+ if (parentB === null) {
126
+ // There is no alternate. This is an unusual case. Currently, it only
127
+ // happens when a Suspense component is hidden. An extra fragment fiber
128
+ // is inserted in between the Suspense fiber and its children. Skip
129
+ // over this extra fragment fiber and proceed to the next parent.
130
+ const nextParent = parentA.return;
131
+ if (nextParent !== null) {
132
+ a = b = nextParent;
133
+ continue;
134
}
135
+ // If there's no parent, we're at the root.
136
+ break;
137
}
138
139
// If both copies of the parent fiber point to the same child, we can