-
Notifications
You must be signed in to change notification settings - Fork 47.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Track nearest Suspense handler on stack (#24585)
* [FORKED] Add HiddenContext to track if subtree is hidden This adds a new stack cursor for tracking whether we're rendering inside a subtree that's currently hidden. This corresponds to the same place where we're already tracking the "base lanes" needed to reveal a hidden subtree — that is, when going from hidden -> visible, the base lanes are the ones that we skipped over when we deferred the subtree. We must includes all the base lanes and their updates in order to avoid an inconsistency with the surrounding content that already committed. I consolidated the base lanes logic and the hidden logic into the same set of push/pop calls. This is intended to replace the InvisibleParentContext that is currently part of SuspenseContext, but I haven't done that part yet. * Add previous commit to forked revisions * [FORKED] Track nearest Suspense handler on stack Instead of traversing the return path whenever something suspends to find the nearest Suspense boundary, we can push the Suspense boundary onto the stack before entering its subtree. This doesn't affect the overall algorithm that much, but because we already do all the same logic in the begin phase, we can save some redundant work by tracking that information on the stack instead of recomputing it every time. * Add previous commit to forked revisions
- Loading branch information
Showing
10 changed files
with
316 additions
and
265 deletions.
There are no files selected for viewing
180 changes: 86 additions & 94 deletions
180
packages/react-reconciler/src/ReactFiberBeginWork.new.js
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
70 changes: 70 additions & 0 deletions
70
packages/react-reconciler/src/ReactFiberHiddenContext.new.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
/** | ||
* Copyright (c) Facebook, Inc. and its affiliates. | ||
* | ||
* This source code is licensed under the MIT license found in the | ||
* LICENSE file in the root directory of this source tree. | ||
* | ||
* @flow | ||
*/ | ||
|
||
import type {Fiber} from './ReactInternalTypes'; | ||
import type {StackCursor} from './ReactFiberStack.new'; | ||
import type {Lanes} from './ReactFiberLane.new'; | ||
|
||
import {createCursor, push, pop} from './ReactFiberStack.new'; | ||
|
||
import {getRenderLanes, setRenderLanes} from './ReactFiberWorkLoop.new'; | ||
import {NoLanes, mergeLanes} from './ReactFiberLane.new'; | ||
|
||
// TODO: Remove `renderLanes` context in favor of hidden context | ||
type HiddenContext = { | ||
// Represents the lanes that must be included when processing updates in | ||
// order to reveal the hidden content. | ||
// TODO: Remove `subtreeLanes` context from work loop in favor of this one. | ||
baseLanes: number, | ||
}; | ||
|
||
// TODO: This isn't being used yet, but it's intended to replace the | ||
// InvisibleParentContext that is currently managed by SuspenseContext. | ||
export const currentTreeHiddenStackCursor: StackCursor<HiddenContext | null> = createCursor( | ||
null, | ||
); | ||
export const prevRenderLanesStackCursor: StackCursor<Lanes> = createCursor( | ||
NoLanes, | ||
); | ||
|
||
export function pushHiddenContext(fiber: Fiber, context: HiddenContext): void { | ||
const prevRenderLanes = getRenderLanes(); | ||
push(prevRenderLanesStackCursor, prevRenderLanes, fiber); | ||
push(currentTreeHiddenStackCursor, context, fiber); | ||
|
||
// When rendering a subtree that's currently hidden, we must include all | ||
// lanes that would have rendered if the hidden subtree hadn't been deferred. | ||
// That is, in order to reveal content from hidden -> visible, we must commit | ||
// all the updates that we skipped when we originally hid the tree. | ||
setRenderLanes(mergeLanes(prevRenderLanes, context.baseLanes)); | ||
} | ||
|
||
export function reuseHiddenContextOnStack(fiber: Fiber): void { | ||
// This subtree is not currently hidden, so we don't need to add any lanes | ||
// to the render lanes. But we still need to push something to avoid a | ||
// context mismatch. Reuse the existing context on the stack. | ||
push(prevRenderLanesStackCursor, getRenderLanes(), fiber); | ||
push( | ||
currentTreeHiddenStackCursor, | ||
currentTreeHiddenStackCursor.current, | ||
fiber, | ||
); | ||
} | ||
|
||
export function popHiddenContext(fiber: Fiber): void { | ||
// Restore the previous render lanes from the stack | ||
setRenderLanes(prevRenderLanesStackCursor.current); | ||
|
||
pop(currentTreeHiddenStackCursor, fiber); | ||
pop(prevRenderLanesStackCursor, fiber); | ||
} | ||
|
||
export function isCurrentTreeHidden() { | ||
return currentTreeHiddenStackCursor.current !== null; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
// Intentionally blank. File only exists in new reconciler fork. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.