@@ -140,4 +140,52 @@ describe('ReactInterleavedUpdates', () => {
140
140
expect ( Scheduler ) . toHaveYielded ( [ 2 , 2 , 2 ] ) ;
141
141
expect ( root ) . toMatchRenderedOutput ( '222' ) ;
142
142
} ) ;
143
+
144
+ test ( 'regression for #24350: does not add to main update queue until interleaved update queue has been cleared' , async ( ) => {
145
+ let setStep ;
146
+ function App ( ) {
147
+ const [ step , _setState ] = useState ( 0 ) ;
148
+ setStep = _setState ;
149
+ return (
150
+ < >
151
+ < Text text = { 'A' + step } />
152
+ < Text text = { 'B' + step } />
153
+ < Text text = { 'C' + step } />
154
+ </ >
155
+ ) ;
156
+ }
157
+
158
+ const root = ReactNoop . createRoot ( ) ;
159
+ await act ( async ( ) => {
160
+ root . render ( < App /> ) ;
161
+ } ) ;
162
+ expect ( Scheduler ) . toHaveYielded ( [ 'A0' , 'B0' , 'C0' ] ) ;
163
+ expect ( root ) . toMatchRenderedOutput ( 'A0B0C0' ) ;
164
+
165
+ await act ( async ( ) => {
166
+ // Start the render phase.
167
+ startTransition ( ( ) => {
168
+ setStep ( 1 ) ;
169
+ } ) ;
170
+ expect ( Scheduler ) . toFlushAndYieldThrough ( [ 'A1' , 'B1' ] ) ;
171
+
172
+ // Schedule an interleaved update. This gets placed on a special queue.
173
+ startTransition ( ( ) => {
174
+ setStep ( 2 ) ;
175
+ } ) ;
176
+
177
+ // Finish rendering the first update.
178
+ expect ( Scheduler ) . toFlushUntilNextPaint ( [ 'C1' ] ) ;
179
+
180
+ // Schedule another update. (In the regression case, this was treated
181
+ // as a normal, non-interleaved update and it was inserted into the queue
182
+ // before the interleaved one was processed.)
183
+ startTransition ( ( ) => {
184
+ setStep ( 3 ) ;
185
+ } ) ;
186
+ } ) ;
187
+ // The last update should win.
188
+ expect ( Scheduler ) . toHaveYielded ( [ 'A3' , 'B3' , 'C3' ] ) ;
189
+ expect ( root ) . toMatchRenderedOutput ( 'A3B3C3' ) ;
190
+ } ) ;
143
191
} ) ;
0 commit comments