-
Notifications
You must be signed in to change notification settings - Fork 47.2k
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
[Synchronous Suspense] Reuse deletions from primary tree #14133
Changes from all commits
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 |
---|---|---|
|
@@ -82,6 +82,7 @@ import { | |
popHydrationState, | ||
} from './ReactFiberHydrationContext'; | ||
import {ConcurrentMode, NoContext} from './ReactTypeOfMode'; | ||
import {reconcileChildFibers} from './ReactChildFiber'; | ||
|
||
function markUpdate(workInProgress: Fiber) { | ||
// Tag the fiber with an update effect. This turns a Placement into | ||
|
@@ -700,12 +701,29 @@ function completeWork( | |
if ((workInProgress.effectTag & DidCapture) !== NoEffect) { | ||
// Something suspended. Re-render with the fallback children. | ||
workInProgress.expirationTime = renderExpirationTime; | ||
workInProgress.firstEffect = workInProgress.lastEffect = null; | ||
// Do not reset the effect list. | ||
return workInProgress; | ||
} | ||
|
||
const nextDidTimeout = nextState !== null; | ||
const prevDidTimeout = current !== null && current.memoizedState !== null; | ||
|
||
if (current !== null && !nextDidTimeout && prevDidTimeout) { | ||
// We just switched from the fallback to the normal children. Delete | ||
// the fallback. | ||
// TODO: Would it be better to store the fallback fragment on | ||
// the stateNode during the begin phase? | ||
const currentFallbackChild: Fiber | null = (current.child: any).sibling; | ||
if (currentFallbackChild !== null) { | ||
reconcileChildFibers( | ||
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. Would it be simpler if instead of deleting the fallback we kept it hidden? Although that seems bad from memory perspective. 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 would be simpler because we would always render two fragments, instead of switching between fragments and no fragments like we do now. That's why (I keep trying to think of a good fuzz test, but I can't. Haven't given up though.) |
||
workInProgress, | ||
currentFallbackChild, | ||
null, | ||
renderExpirationTime, | ||
); | ||
} | ||
} | ||
|
||
// The children either timed out after previously being visible, or | ||
// were restored after previously being hidden. Schedule an effect | ||
// to update their visiblity. | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -993,7 +993,6 @@ function completeUnitOfWork(workInProgress: Fiber): Fiber | null { | |
|
||
if (nextUnitOfWork !== null) { | ||
// Completing this fiber spawned new work. Work on that next. | ||
nextUnitOfWork.firstEffect = nextUnitOfWork.lastEffect = null; | ||
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. So this was the thing that caused us to "forget" about deletions? 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. Yes |
||
return nextUnitOfWork; | ||
} | ||
|
||
|
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.
Why would it be better?
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.
To avoid the confusing series of checks this comment is wrapped in. Could be replaced by checking if the stateNode is null.
I'm not sure that's actually better though. Kinda gross either way.