Skip to content

Commit fc298f5

Browse files
committed
Only fire effects for Offscreen when it is revealed
1 parent 3523be2 commit fc298f5

File tree

3 files changed

+31
-6
lines changed

3 files changed

+31
-6
lines changed

packages/react-reconciler/src/ReactFiberWorkLoop.new.js

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3188,9 +3188,12 @@ function doubleInvokeEffectsInDEV(
31883188

31893189
if (fiber.flags & PlacementDEV || fiber.tag === OffscreenComponent) {
31903190
setCurrentDebugFiberInDEV(fiber);
3191-
const hasOffscreenVisibilityFlag =
3192-
fiber.tag !== OffscreenComponent || fiber.flags & Visibility;
3193-
if (isInStrictMode && hasOffscreenVisibilityFlag) {
3191+
const isNotOffscreen = fiber.tag !== OffscreenComponent;
3192+
// Checks if Offscreen is being revealed. For all other components, evaluates to true.
3193+
const hasOffscreenBecomeVisible =
3194+
isNotOffscreen ||
3195+
(fiber.flags & Visibility && fiber.memoizedState === null);
3196+
if (isInStrictMode && hasOffscreenBecomeVisible) {
31943197
disappearLayoutEffects(fiber);
31953198
disconnectPassiveEffect(fiber);
31963199
reappearLayoutEffects(root, fiber.alternate, fiber, false);

packages/react-reconciler/src/ReactFiberWorkLoop.old.js

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3188,9 +3188,12 @@ function doubleInvokeEffectsInDEV(
31883188

31893189
if (fiber.flags & PlacementDEV || fiber.tag === OffscreenComponent) {
31903190
setCurrentDebugFiberInDEV(fiber);
3191-
const hasOffscreenVisibilityFlag =
3192-
fiber.tag !== OffscreenComponent || fiber.flags & Visibility;
3193-
if (isInStrictMode && hasOffscreenVisibilityFlag) {
3191+
const isNotOffscreen = fiber.tag !== OffscreenComponent;
3192+
// Checks if Offscreen is being revealed. For all other components, evaluates to true.
3193+
const hasOffscreenBecomeVisible =
3194+
isNotOffscreen ||
3195+
(fiber.flags & Visibility && fiber.memoizedState === null);
3196+
if (isInStrictMode && hasOffscreenBecomeVisible) {
31943197
disappearLayoutEffects(fiber);
31953198
disconnectPassiveEffect(fiber);
31963199
reappearLayoutEffects(root, fiber.alternate, fiber, false);

packages/react-reconciler/src/__tests__/ReactOffscreenStrictMode-test.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,25 @@ describe('ReactOffscreenStrictMode', () => {
106106
'A: useLayoutEffect mount',
107107
'A: useEffect mount',
108108
]);
109+
110+
log = [];
111+
112+
act(() => {
113+
ReactNoop.render(
114+
<React.StrictMode>
115+
<Offscreen mode="hidden">
116+
<Component label="A" />
117+
</Offscreen>
118+
</React.StrictMode>,
119+
);
120+
});
121+
122+
expect(log).toEqual([
123+
'A: useLayoutEffect unmount',
124+
'A: useEffect unmount',
125+
'A: render',
126+
'A: render',
127+
]);
109128
});
110129

111130
it('should not cause infinite render loop when StrictMode is used with Suspense and synchronous set states', () => {

0 commit comments

Comments
 (0)