From dc5ed00973d6fbe979aa613b0519a54f150633be Mon Sep 17 00:00:00 2001 From: Andrew Clark Date: Tue, 7 Jun 2022 17:55:41 -0400 Subject: [PATCH] Add `isHidden` to OffscreenInstance We need to be able to read whether an offscreen tree is hidden from an imperative event. We can store this on its OffscreenInstance. We were already scheduling a commit effect whenever the visibility changes, in order to toggle the inner effects. So we can reuse that. --- packages/react-reconciler/src/ReactFiber.new.js | 4 +++- packages/react-reconciler/src/ReactFiber.old.js | 4 +++- .../react-reconciler/src/ReactFiberCommitWork.new.js | 11 +++++++++++ .../react-reconciler/src/ReactFiberCommitWork.old.js | 11 +++++++++++ .../src/ReactFiberOffscreenComponent.js | 4 +++- 5 files changed, 31 insertions(+), 3 deletions(-) diff --git a/packages/react-reconciler/src/ReactFiber.new.js b/packages/react-reconciler/src/ReactFiber.new.js index 33fc93ef9361..58aabf70afa5 100644 --- a/packages/react-reconciler/src/ReactFiber.new.js +++ b/packages/react-reconciler/src/ReactFiber.new.js @@ -715,7 +715,9 @@ export function createFiberFromOffscreen( const fiber = createFiber(OffscreenComponent, pendingProps, key, mode); fiber.elementType = REACT_OFFSCREEN_TYPE; fiber.lanes = lanes; - const primaryChildInstance: OffscreenInstance = {}; + const primaryChildInstance: OffscreenInstance = { + isHidden: false, + }; fiber.stateNode = primaryChildInstance; return fiber; } diff --git a/packages/react-reconciler/src/ReactFiber.old.js b/packages/react-reconciler/src/ReactFiber.old.js index a65f460c6b27..afa8f26503cc 100644 --- a/packages/react-reconciler/src/ReactFiber.old.js +++ b/packages/react-reconciler/src/ReactFiber.old.js @@ -715,7 +715,9 @@ export function createFiberFromOffscreen( const fiber = createFiber(OffscreenComponent, pendingProps, key, mode); fiber.elementType = REACT_OFFSCREEN_TYPE; fiber.lanes = lanes; - const primaryChildInstance: OffscreenInstance = {}; + const primaryChildInstance: OffscreenInstance = { + isHidden: false, + }; fiber.stateNode = primaryChildInstance; return fiber; } diff --git a/packages/react-reconciler/src/ReactFiberCommitWork.new.js b/packages/react-reconciler/src/ReactFiberCommitWork.new.js index d023c1f776b3..8448f8c25eb2 100644 --- a/packages/react-reconciler/src/ReactFiberCommitWork.new.js +++ b/packages/react-reconciler/src/ReactFiberCommitWork.new.js @@ -2309,8 +2309,14 @@ function commitMutationEffectsOnFiber( const offscreenFiber: Fiber = (finishedWork.child: any); if (offscreenFiber.flags & Visibility) { + const offscreenInstance: OffscreenInstance = offscreenFiber.stateNode; const newState: OffscreenState | null = offscreenFiber.memoizedState; const isHidden = newState !== null; + + // Track the current state on the Offscreen instance so we can + // read it during an event + offscreenInstance.isHidden = isHidden; + if (isHidden) { const wasHidden = offscreenFiber.alternate !== null && @@ -2354,10 +2360,15 @@ function commitMutationEffectsOnFiber( commitReconciliationEffects(finishedWork); if (flags & Visibility) { + const offscreenInstance: OffscreenInstance = finishedWork.stateNode; const newState: OffscreenState | null = finishedWork.memoizedState; const isHidden = newState !== null; const offscreenBoundary: Fiber = finishedWork; + // Track the current state on the Offscreen instance so we can + // read it during an event + offscreenInstance.isHidden = isHidden; + if (enableSuspenseLayoutEffectSemantics) { if (isHidden) { if (!wasHidden) { diff --git a/packages/react-reconciler/src/ReactFiberCommitWork.old.js b/packages/react-reconciler/src/ReactFiberCommitWork.old.js index a9eae21939df..ab273999764b 100644 --- a/packages/react-reconciler/src/ReactFiberCommitWork.old.js +++ b/packages/react-reconciler/src/ReactFiberCommitWork.old.js @@ -2309,8 +2309,14 @@ function commitMutationEffectsOnFiber( const offscreenFiber: Fiber = (finishedWork.child: any); if (offscreenFiber.flags & Visibility) { + const offscreenInstance: OffscreenInstance = offscreenFiber.stateNode; const newState: OffscreenState | null = offscreenFiber.memoizedState; const isHidden = newState !== null; + + // Track the current state on the Offscreen instance so we can + // read it during an event + offscreenInstance.isHidden = isHidden; + if (isHidden) { const wasHidden = offscreenFiber.alternate !== null && @@ -2354,10 +2360,15 @@ function commitMutationEffectsOnFiber( commitReconciliationEffects(finishedWork); if (flags & Visibility) { + const offscreenInstance: OffscreenInstance = finishedWork.stateNode; const newState: OffscreenState | null = finishedWork.memoizedState; const isHidden = newState !== null; const offscreenBoundary: Fiber = finishedWork; + // Track the current state on the Offscreen instance so we can + // read it during an event + offscreenInstance.isHidden = isHidden; + if (enableSuspenseLayoutEffectSemantics) { if (isHidden) { if (!wasHidden) { diff --git a/packages/react-reconciler/src/ReactFiberOffscreenComponent.js b/packages/react-reconciler/src/ReactFiberOffscreenComponent.js index 05952f77a0fd..b43188103e6f 100644 --- a/packages/react-reconciler/src/ReactFiberOffscreenComponent.js +++ b/packages/react-reconciler/src/ReactFiberOffscreenComponent.js @@ -38,4 +38,6 @@ export type OffscreenQueue = {| transitions: Array | null, |} | null; -export type OffscreenInstance = {}; +export type OffscreenInstance = {| + isHidden: boolean, +|};