From d51fff3122c48e6c21df21e452559eef18b532e9 Mon Sep 17 00:00:00 2001 From: Dan Abramov Date: Mon, 11 Feb 2019 14:33:00 +0000 Subject: [PATCH] Fix batching --- .../src/__tests__/ReactDOMHooks-test.js | 36 +++++++++++++++++++ .../src/ReactFiberScheduler.js | 2 +- 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/packages/react-dom/src/__tests__/ReactDOMHooks-test.js b/packages/react-dom/src/__tests__/ReactDOMHooks-test.js index 399751cb7ef62..fe6caa82198da 100644 --- a/packages/react-dom/src/__tests__/ReactDOMHooks-test.js +++ b/packages/react-dom/src/__tests__/ReactDOMHooks-test.js @@ -70,6 +70,42 @@ describe('ReactDOMHooks', () => { expect(container3.textContent).toBe('6'); }); + it('can batch synchronous work inside effects with other work', () => { + let otherContainer = document.createElement('div'); + + let calledA = false; + function A() { + calledA = true; + return 'A'; + } + + let calledB = false; + function B() { + calledB = true; + return 'B'; + } + + let _set; + function Foo() { + _set = React.useState(0)[1]; + React.useEffect(() => { + ReactDOM.render(, otherContainer); + }); + return null; + } + + ReactDOM.render(, container); + ReactDOM.unstable_batchedUpdates(() => { + _set(0); // Forces the effect to be flushed + expect(otherContainer.textContent).toBe(''); + ReactDOM.render(, otherContainer); + expect(otherContainer.textContent).toBe(''); + }); + expect(otherContainer.textContent).toBe('B'); + expect(calledA).toBe(false); // It was in a batch + expect(calledB).toBe(true); + }); + it('should not bail out when an update is scheduled from within an event handler', () => { const {createRef, useCallback, useState} = React; diff --git a/packages/react-reconciler/src/ReactFiberScheduler.js b/packages/react-reconciler/src/ReactFiberScheduler.js index 783ec2ed272db..2e05987a3d3d4 100644 --- a/packages/react-reconciler/src/ReactFiberScheduler.js +++ b/packages/react-reconciler/src/ReactFiberScheduler.js @@ -573,7 +573,7 @@ function commitPassiveEffects(root: FiberRoot, firstEffect: Fiber): void { requestWork(root, rootExpirationTime); } // Flush any sync work that was scheduled by effects - if (!isRendering) { + if (!isBatchingUpdates && !isRendering) { performSyncWork(); } }