@@ -16,6 +16,11 @@ let ReactDOM;
1616
1717const AsyncMode = React . unstable_AsyncMode ;
1818
19+ const setUntrackedInputValue = Object . getOwnPropertyDescriptor (
20+ HTMLInputElement . prototype ,
21+ 'value' ,
22+ ) . set ;
23+
1924describe ( 'ReactDOMFiberAsync' , ( ) => {
2025 let container ;
2126
@@ -47,6 +52,12 @@ describe('ReactDOMFiberAsync', () => {
4752 jest . resetModules ( ) ;
4853 container = document . createElement ( 'div' ) ;
4954 ReactDOM = require ( 'react-dom' ) ;
55+
56+ document . body . appendChild ( container ) ;
57+ } ) ;
58+
59+ afterEach ( ( ) => {
60+ document . body . removeChild ( container ) ;
5061 } ) ;
5162
5263 it ( 'renders synchronously by default' , ( ) => {
@@ -60,11 +71,53 @@ describe('ReactDOMFiberAsync', () => {
6071 expect ( ops ) . toEqual ( [ 'Hi' , 'Bye' ] ) ;
6172 } ) ;
6273
74+ it ( 'does not perform deferred updates synchronously' , ( ) => {
75+ let inputRef = React . createRef ( ) ;
76+ let contentRef = React . createRef ( ) ;
77+
78+ class Counter extends React . Component {
79+ state = { asyncValue : '' } ;
80+
81+ handleChange = e => {
82+ const nextValue = e . target . value ;
83+ ReactDOM . unstable_deferredUpdates ( ( ) => {
84+ this . setState ( {
85+ asyncValue : nextValue ,
86+ } ) ;
87+ } ) ;
88+ } ;
89+
90+ render ( ) {
91+ return (
92+ < div >
93+ < input
94+ ref = { inputRef }
95+ onChange = { this . handleChange }
96+ defaultValue = ""
97+ />
98+ < p ref = { contentRef } > { this . state . asyncValue } </ p >
99+ </ div >
100+ ) ;
101+ }
102+ }
103+ ReactDOM . render ( < Counter /> , container ) ;
104+ expect ( contentRef . current . textContent ) . toBe ( '' ) ;
105+
106+ setUntrackedInputValue . call ( inputRef . current , 'hello' ) ;
107+ inputRef . current . dispatchEvent ( new MouseEvent ( 'input' , { bubbles : true } ) ) ;
108+
109+ // Should not flush yet because it's a deferred update.
110+ expect ( contentRef . current . textContent ) . toBe ( '' ) ;
111+
112+ // Should flush now.
113+ jest . runAllTimers ( ) ;
114+ expect ( contentRef . current . textContent ) . toBe ( 'hello' ) ;
115+ } ) ;
116+
63117 describe ( 'with feature flag disabled' , ( ) => {
64118 beforeEach ( ( ) => {
65119 jest . resetModules ( ) ;
66120 ReactFeatureFlags = require ( 'shared/ReactFeatureFlags' ) ;
67- container = document . createElement ( 'div' ) ;
68121 ReactDOM = require ( 'react-dom' ) ;
69122 } ) ;
70123
@@ -91,7 +144,6 @@ describe('ReactDOMFiberAsync', () => {
91144 beforeEach ( ( ) => {
92145 jest . resetModules ( ) ;
93146 ReactFeatureFlags = require ( 'shared/ReactFeatureFlags' ) ;
94- container = document . createElement ( 'div' ) ;
95147 ReactFeatureFlags . debugRenderPhaseSideEffectsForStrictMode = false ;
96148 ReactDOM = require ( 'react-dom' ) ;
97149 } ) ;
0 commit comments