Skip to content

Commit

Permalink
Regression test: Interleaved update race condition
Browse files Browse the repository at this point in the history
Demonstrates the bug reported in facebook#24350.
  • Loading branch information
acdlite committed Apr 12, 2022
1 parent 0568c0f commit f05029d
Showing 1 changed file with 48 additions and 0 deletions.
Expand Up @@ -140,4 +140,52 @@ describe('ReactInterleavedUpdates', () => {
expect(Scheduler).toHaveYielded([2, 2, 2]);
expect(root).toMatchRenderedOutput('222');
});

test('regression for #24350: does not add to main update queue until interleaved update queue has been cleared', async () => {
let setStep;
function App() {
const [step, _setState] = useState(0);
setStep = _setState;
return (
<>
<Text text={'A' + step} />
<Text text={'B' + step} />
<Text text={'C' + step} />
</>
);
}

const root = ReactNoop.createRoot();
await act(async () => {
root.render(<App />);
});
expect(Scheduler).toHaveYielded(['A0', 'B0', 'C0']);
expect(root).toMatchRenderedOutput('A0B0C0');

await act(async () => {
// Start the render phase.
startTransition(() => {
setStep(1);
});
expect(Scheduler).toFlushAndYieldThrough(['A1', 'B1']);

// Schedule an interleaved update. This gets placed on a special queue.
startTransition(() => {
setStep(2);
});

// Finish rendering the first update.
expect(Scheduler).toFlushUntilNextPaint(['C1']);

// Schedule another update. (In the regression case, this was treated
// as a normal, non-interleaved update and it was inserted into the queue
// before the interleaved one was processed.)
startTransition(() => {
setStep(3);
});
});
// The last update should win.
expect(Scheduler).toHaveYielded(['A3', 'B3', 'C3']);
expect(root).toMatchRenderedOutput('A3B3C3');
});
});

0 comments on commit f05029d

Please sign in to comment.