Fix findDOMNode algorithm
This commit is contained in:
parent
ec936dd848
commit
97f6786cba
|
@ -101,17 +101,16 @@ function findCurrentFiberUsingSlowPath(fiber : Fiber) : Fiber | null {
|
||||||
let b = alternate;
|
let b = alternate;
|
||||||
while (true) {
|
while (true) {
|
||||||
let parentA = a.return;
|
let parentA = a.return;
|
||||||
let parentB = b.return;
|
let parentB = parentA ? parentA.alternate : null;
|
||||||
if (!parentA || !parentB) {
|
if (!parentA || !parentB) {
|
||||||
// We're at the root.
|
// We're at the root.
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If both copies of the parent fiber point to the same child, we can
|
||||||
|
// assume that the child is current. This happens when we bailout on low
|
||||||
|
// priority: the bailed out fiber's child reuses the current child.
|
||||||
if (parentA.child === parentB.child) {
|
if (parentA.child === parentB.child) {
|
||||||
// If both parents are the same, then that is the current parent. If
|
|
||||||
// they're different but point to the same child, then it doesn't matter.
|
|
||||||
// Regardless, whatever child they point to is the current child.
|
|
||||||
// So we can now determine which child is current by scanning the child
|
|
||||||
// list for either A or B.
|
|
||||||
let child = parentA.child;
|
let child = parentA.child;
|
||||||
while (child) {
|
while (child) {
|
||||||
if (child === a) {
|
if (child === a) {
|
||||||
|
@ -133,8 +132,56 @@ function findCurrentFiberUsingSlowPath(fiber : Fiber) : Fiber | null {
|
||||||
'Unable to find node on an unmounted component.'
|
'Unable to find node on an unmounted component.'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
a = parentA;
|
|
||||||
b = parentB;
|
if (a.return !== b.return) {
|
||||||
|
// The return pointer of A and the return pointer of B point to different
|
||||||
|
// fibers. We assume that return pointers never criss-cross, so A must
|
||||||
|
// belong to the child set of A.return, and B must belong to the child
|
||||||
|
// set of B.return.
|
||||||
|
a = parentA;
|
||||||
|
b = parentB;
|
||||||
|
} else {
|
||||||
|
// The return pointers pointer to the same fiber. We'll have to use the
|
||||||
|
// default, slow path: scan the child sets of each parent alternate to see
|
||||||
|
// which child belongs to which set.
|
||||||
|
//
|
||||||
|
// Search parent A's child set
|
||||||
|
let didFindChild = false;
|
||||||
|
let child = parentA.child;
|
||||||
|
while (child) {
|
||||||
|
if (child === a) {
|
||||||
|
didFindChild = true;
|
||||||
|
a = parentA;
|
||||||
|
b = parentB;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (child === b) {
|
||||||
|
didFindChild = true;
|
||||||
|
b = parentA;
|
||||||
|
a = parentB;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
child = child.sibling;
|
||||||
|
}
|
||||||
|
if (!didFindChild) {
|
||||||
|
// Search parent B's child set
|
||||||
|
child = parentB.child;
|
||||||
|
while (child) {
|
||||||
|
if (child === a) {
|
||||||
|
a = parentB;
|
||||||
|
b = parentA;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (child === b) {
|
||||||
|
b = parentB;
|
||||||
|
a = parentA;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
child = child.sibling;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
invariant(
|
invariant(
|
||||||
a.alternate === b,
|
a.alternate === b,
|
||||||
'Return fibers should always be each others\' alternates.'
|
'Return fibers should always be each others\' alternates.'
|
||||||
|
|
Loading…
Reference in New Issue