-
Notifications
You must be signed in to change notification settings - Fork 46.8k
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 Ref Lifecycles in Hidden Subtrees #31379
Changes from 2 commits
bdfe9fe
a2c9e7a
2101de0
1426f6d
52c0e97
a0685eb
4036c91
1b7c7ee
dc0c3a5
82bea69
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1325,7 +1325,9 @@ function commitDeletionEffectsOnFiber( | |
} | ||
case ScopeComponent: { | ||
if (enableScopeAPI) { | ||
safelyDetachRef(deletedFiber, nearestMountedAncestor); | ||
if (!offscreenSubtreeWasHidden) { | ||
safelyDetachRef(deletedFiber, nearestMountedAncestor); | ||
} | ||
} | ||
recursivelyTraverseDeletionEffects( | ||
finishedRoot, | ||
|
@@ -1335,7 +1337,9 @@ function commitDeletionEffectsOnFiber( | |
return; | ||
} | ||
case OffscreenComponent: { | ||
safelyDetachRef(deletedFiber, nearestMountedAncestor); | ||
if (!offscreenSubtreeWasHidden) { | ||
safelyDetachRef(deletedFiber, nearestMountedAncestor); | ||
} | ||
if (disableLegacyMode || deletedFiber.mode & ConcurrentMode) { | ||
// If this offscreen component is hidden, we already unmounted it. Before | ||
// deleting the children, track that it's already unmounted so that we | ||
|
@@ -1572,7 +1576,7 @@ function recursivelyTraverseMutationEffects( | |
lanes: Lanes, | ||
) { | ||
// Deletions effects can be scheduled on any fiber type. They need to happen | ||
// before the children effects hae fired. | ||
// before the children effects have fired. | ||
const deletions = parentFiber.deletions; | ||
if (deletions !== null) { | ||
for (let i = 0; i < deletions.length; i++) { | ||
|
@@ -1636,7 +1640,7 @@ function commitMutationEffectsOnFiber( | |
recursivelyTraverseMutationEffects(root, finishedWork, lanes); | ||
commitReconciliationEffects(finishedWork); | ||
|
||
if (flags & Ref) { | ||
if (flags & Ref && !offscreenSubtreeWasHidden) { | ||
if (current !== null) { | ||
safelyDetachRef(current, current.return); | ||
} | ||
|
@@ -1659,7 +1663,7 @@ function commitMutationEffectsOnFiber( | |
recursivelyTraverseMutationEffects(root, finishedWork, lanes); | ||
commitReconciliationEffects(finishedWork); | ||
|
||
if (flags & Ref) { | ||
if (flags & Ref && !offscreenSubtreeWasHidden) { | ||
if (current !== null) { | ||
safelyDetachRef(current, current.return); | ||
} | ||
|
@@ -1744,7 +1748,7 @@ function commitMutationEffectsOnFiber( | |
recursivelyTraverseMutationEffects(root, finishedWork, lanes); | ||
commitReconciliationEffects(finishedWork); | ||
|
||
if (flags & Ref) { | ||
if (flags & Ref && !offscreenSubtreeWasHidden) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For the Jest unit test that @rickhanlonii added in a2c9e7a, this is the only line that is actually necessary to fix the unit test. |
||
if (current !== null) { | ||
safelyDetachRef(current, current.return); | ||
} | ||
|
@@ -1960,7 +1964,7 @@ function commitMutationEffectsOnFiber( | |
break; | ||
} | ||
case OffscreenComponent: { | ||
if (flags & Ref) { | ||
if (flags & Ref && !offscreenSubtreeWasHidden) { | ||
if (current !== null) { | ||
safelyDetachRef(current, current.return); | ||
} | ||
|
@@ -2073,7 +2077,7 @@ function commitMutationEffectsOnFiber( | |
|
||
// TODO: This is a temporary solution that allowed us to transition away | ||
// from React Flare on www. | ||
if (flags & Ref) { | ||
if (flags & Ref && !offscreenSubtreeWasHidden) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It doesn't seem clear to me if the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Conceptually, it makes sense to skip both. I'm not sure why |
||
if (current !== null) { | ||
safelyDetachRef(finishedWork, finishedWork.return); | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the unit test for "ignores ref for Activity in hidden subtree", I discovered that this and the call from
commitMutationEffectsOnFiber
are triggered, causingX
to be incorrectly invoked twice! 🤯