diff --git a/packages/react-reconciler/src/__tests__/ReactSuspenseWithNoopRenderer-test.js b/packages/react-reconciler/src/__tests__/ReactSuspenseWithNoopRenderer-test.js
index cfe3d244b510..5f5469bcd904 100644
--- a/packages/react-reconciler/src/__tests__/ReactSuspenseWithNoopRenderer-test.js
+++ b/packages/react-reconciler/src/__tests__/ReactSuspenseWithNoopRenderer-test.js
@@ -3869,4 +3869,53 @@ describe('ReactSuspenseWithNoopRenderer', () => {
expect(root).toMatchRenderedOutput();
});
});
+
+ it('regression: #18657', async () => {
+ const {useState} = React;
+
+ let setText;
+ function App() {
+ const [text, _setText] = useState('A');
+ setText = _setText;
+ return ;
+ }
+
+ const root = ReactNoop.createRoot();
+ await ReactNoop.act(async () => {
+ await resolveText('A');
+ root.render(
+ }>
+
+ ,
+ );
+ });
+ expect(Scheduler).toHaveYielded(['A']);
+ expect(root).toMatchRenderedOutput();
+
+ await ReactNoop.act(async () => {
+ setText('B');
+ Scheduler.unstable_runWithPriority(
+ Scheduler.unstable_IdlePriority,
+ () => {
+ setText('B');
+ },
+ );
+ // Suspend the first update. The second update doesn't run because it has
+ // Idle priority.
+ expect(Scheduler).toFlushAndYield(['Suspend! [B]', 'Loading...']);
+
+ // Commit the fallback. Now we'll try working on Idle.
+ jest.runAllTimers();
+
+ // It also suspends.
+ expect(Scheduler).toFlushAndYield(['Suspend! [B]']);
+ });
+
+ await ReactNoop.act(async () => {
+ setText('B');
+ await resolveText('B');
+ });
+ expect(Scheduler).toHaveYielded(['Promise resolved [B]', 'B']);
+ expect(root).toMatchRenderedOutput();
+ });
});