Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix findDOMNode incorrectly failing inside Suspense #14198

Closed
wants to merge 2 commits into from

Conversation

gaearon
Copy link
Collaborator

@gaearon gaearon commented Nov 12, 2018

Builds on #14197. Second test is failing is now fixed.

Based on the test in #14188 (comment) found by @arianon. Unlike the issue from #14197, this one seems like it existed even before the Suspense refactorings. So maybe it was always there.

}

ReactDOM.render(<App />, container);
// expect(log).toEqual([]);
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wasn't sure what's expected here. We'll need to fill those out before merging.

@sophiebits
Copy link
Collaborator

sophiebits commented Dec 6, 2018

I pushed a commit that I think fixes it. If findCurrentFiberUsingSlowPath is called on a fiber that has an alternate whose parent has no alternate, it previously incorrectly thought it had reached the root.

We hit this now and not before because of the Fragment we add under each Suspense child – unlike all other ancestors, it doesn't end up having an alternate.

@sophiebits sophiebits changed the title Add another (failing) regression test for #14188 Fix findDOMNode incorrectly failing inside Suspense Dec 6, 2018
// This happens when we bailout on low priority: the bailed out fiber's
// child reuses the current child.
let parentB = parentA.alternate;
if (!parentB || parentA.child === parentB.child) {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

=== null pls?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's probably better. I had copied the truthy check from the old code.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe Seb wanted it to be slower. Bad bad findDOMNode.

@gaearon
Copy link
Collaborator Author

gaearon commented Dec 7, 2018

Could we be making similar assumptions about presence of alternate elsewhere? Such as in event system traversal logic (eg traverseEnterLeave) or DOM Component Tree?

@sebmarkbage
Copy link
Collaborator

I need to take 7 hours to think about this. Not so sure about this.

But also if you don’t want it to error you should test that the return value is what you expect it to be.

It’s better to error than return the wrong value.

@@ -117,16 +117,17 @@ export function findCurrentFiberUsingSlowPath(fiber: Fiber): Fiber | null {
let b = alternate;
while (true) {
let parentA = a.return;
let parentB = parentA ? parentA.alternate : null;
if (!parentA || !parentB) {
if (!parentA) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don’t think the logic is designed to make assumptions about which side is which. That’s why it’s a and b instead of say current and workInProgress.

This seems to think that A has some different property than B. Why is this?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe the logic should have really been !parentA && !parentB. Then we should enter the next if if either is null. But it is impossible for parentA to be null and parentB to be non-null. Hence the asymmetry. I could write it in a more symmetric way but it would have dead branches.

@sophiebits
Copy link
Collaborator

OK you're right it returns the wrong value. Dang.

@sebmarkbage
Copy link
Collaborator

What even is the right value? It doesn’t have well defined behavior since conceptually the fallback/main content could be first or last or not exist in the tree.

@sebmarkbage
Copy link
Collaborator

I think that in this case you need to skip past the fragment and look at the two parents of the fragment to figure out if they converge.

@sophiebits
Copy link
Collaborator

I think so too. But is it supposed to return the hidden node?

@sophiebits
Copy link
Collaborator

ugh the logic to support suspense properly here looks so complicated

@sebmarkbage
Copy link
Collaborator

Note that Suspense isn’t even done yet. The hydration of Suspense is looking to triple the complexity of Suspense and that’s not even taking findDOMNode into account.

acdlite added a commit to acdlite/react that referenced this pull request Apr 3, 2019
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.
acdlite added a commit to acdlite/react that referenced this pull request Apr 3, 2019
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.
@gaearon
Copy link
Collaborator Author

gaearon commented Apr 9, 2019

This was fixed in #15312

@gaearon gaearon closed this Apr 9, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants