main
js 74 lines 2.65 KB
Raw
1 /**
2 * Copyright (c) Meta Platforms, Inc. and affiliates.
3 *
4 * This source code is licensed under the MIT license found in the
5 * LICENSE file in the root directory of this source tree.
6 *
7 * @flow
8 */
9
10 import type {Fiber} from './ReactInternalTypes';
11 import type {StackCursor} from './ReactFiberStack';
12 import type {Lanes} from './ReactFiberLane';
13
14 import {createCursor, push, pop} from './ReactFiberStack';
15
16 import {
17 getEntangledRenderLanes,
18 setEntangledRenderLanes,
19 } from './ReactFiberWorkLoop';
20 import {NoLanes, mergeLanes} from './ReactFiberLane';
21
22 // TODO: Remove `renderLanes` context in favor of hidden context
23 type HiddenContext = {
24 // Represents the lanes that must be included when processing updates in
25 // order to reveal the hidden content.
26 // TODO: Remove `subtreeLanes` context from work loop in favor of this one.
27 baseLanes: number,
28 ...
29 };
30
31 // TODO: This isn't being used yet, but it's intended to replace the
32 // InvisibleParentContext that is currently managed by SuspenseContext.
33 export const currentTreeHiddenStackCursor: StackCursor<HiddenContext | null> =
34 createCursor(null);
35 export const prevEntangledRenderLanesCursor: StackCursor<Lanes> =
36 createCursor(NoLanes);
37
38 export function pushHiddenContext(fiber: Fiber, context: HiddenContext): void {
39 const prevEntangledRenderLanes = getEntangledRenderLanes();
40 push(prevEntangledRenderLanesCursor, prevEntangledRenderLanes, fiber);
41 push(currentTreeHiddenStackCursor, context, fiber);
42
43 // When rendering a subtree that's currently hidden, we must include all
44 // lanes that would have rendered if the hidden subtree hadn't been deferred.
45 // That is, in order to reveal content from hidden -> visible, we must commit
46 // all the updates that we skipped when we originally hid the tree.
47 setEntangledRenderLanes(
48 mergeLanes(prevEntangledRenderLanes, context.baseLanes),
49 );
50 }
51
52 export function reuseHiddenContextOnStack(fiber: Fiber): void {
53 // This subtree is not currently hidden, so we don't need to add any lanes
54 // to the render lanes. But we still need to push something to avoid a
55 // context mismatch. Reuse the existing context on the stack.
56 push(prevEntangledRenderLanesCursor, getEntangledRenderLanes(), fiber);
57 push(
58 currentTreeHiddenStackCursor,
59 currentTreeHiddenStackCursor.current,
60 fiber,
61 );
62 }
63
64 export function popHiddenContext(fiber: Fiber): void {
65 // Restore the previous render lanes from the stack
66 setEntangledRenderLanes(prevEntangledRenderLanesCursor.current);
67
68 pop(currentTreeHiddenStackCursor, fiber);
69 pop(prevEntangledRenderLanesCursor, fiber);
70 }
71
72 export function isCurrentTreeHidden(): boolean {
73 return currentTreeHiddenStackCursor.current !== null;
74 }