From 62406b029ef4bb2b1d251a246218b2f75aefc6b7 Mon Sep 17 00:00:00 2001 From: Andrew Clark Date: Thu, 23 May 2019 13:13:41 -0700 Subject: [PATCH] Support `hidden` deprioritization in Batched Mode Hidden trees will tear and commit in a separate render, as in Concurrent Mode. Unlike Concurrent Mode, once the hidden tree begins, it will finish without yielding. --- .../src/ReactFiberBeginWork.js | 10 +---- .../src/ReactFiberScheduler.js | 5 +++ .../ReactBatchedMode-test.internal.js | 42 +++++++++++++++++++ 3 files changed, 49 insertions(+), 8 deletions(-) diff --git a/packages/react-reconciler/src/ReactFiberBeginWork.js b/packages/react-reconciler/src/ReactFiberBeginWork.js index b6cd356197d6d..36b33f0fb32e9 100644 --- a/packages/react-reconciler/src/ReactFiberBeginWork.js +++ b/packages/react-reconciler/src/ReactFiberBeginWork.js @@ -84,13 +84,7 @@ import { Never, computeAsyncExpiration, } from './ReactFiberExpirationTime'; -import { - ConcurrentMode, - NoMode, - ProfileMode, - StrictMode, - BatchedMode, -} from './ReactTypeOfMode'; +import {NoMode, ProfileMode, StrictMode, BatchedMode} from './ReactTypeOfMode'; import { shouldSetTextContent, shouldDeprioritizeSubtree, @@ -980,7 +974,7 @@ function updateHostComponent(current, workInProgress, renderExpirationTime) { // Check the host config to see if the children are offscreen/hidden. if ( - workInProgress.mode & ConcurrentMode && + workInProgress.mode & BatchedMode && renderExpirationTime !== Never && shouldDeprioritizeSubtree(type, nextProps) ) { diff --git a/packages/react-reconciler/src/ReactFiberScheduler.js b/packages/react-reconciler/src/ReactFiberScheduler.js index 3d7d17840bd48..9af59f8f542bf 100644 --- a/packages/react-reconciler/src/ReactFiberScheduler.js +++ b/packages/react-reconciler/src/ReactFiberScheduler.js @@ -64,6 +64,7 @@ import { BatchedMode, ConcurrentMode, } from './ReactTypeOfMode'; +import {ConcurrentRoot} from 'shared/ReactRootTags'; import { HostRoot, ClassComponent, @@ -776,6 +777,10 @@ function renderRoot( 'Should not already be working.', ); + if (root.tag !== ConcurrentRoot) { + isSync = true; + } + if (enableUserTimingAPI && expirationTime !== Sync) { const didExpire = isSync; stopRequestCallbackTimer(didExpire); diff --git a/packages/react-reconciler/src/__tests__/ReactBatchedMode-test.internal.js b/packages/react-reconciler/src/__tests__/ReactBatchedMode-test.internal.js index ea33035ca37a2..a4884c513056f 100644 --- a/packages/react-reconciler/src/__tests__/ReactBatchedMode-test.internal.js +++ b/packages/react-reconciler/src/__tests__/ReactBatchedMode-test.internal.js @@ -161,4 +161,46 @@ describe('ReactBatchedMode', () => { expect(Scheduler).toFlushExpired(['A1']); expect(root).toMatchRenderedOutput('A1B1'); }); + + it('hidden subtrees are deprioritized but not yieldy', () => { + const {useEffect} = React; + + const root = ReactNoop.createSyncRoot(); + function App() { + useEffect(() => Scheduler.yieldValue('Commit')); + return ( + }> + +
+ + + +
+
+ ); + } + + root.render(); + expect(Scheduler).toFlushAndYieldThrough(['D', 'E', 'F', 'Commit']); + expect(root).toMatchRenderedOutput( + +