Skip to content

Commit 24e2806

Browse files
acdlitesebmarkbage
authored andcommitted
Failing test: Updates "un-committed" when rebasing
Adds a failing test case where an update that was committed is later skipped over during a rebase. This should never happen.
1 parent dc18b8b commit 24e2806

File tree

1 file changed

+64
-0
lines changed

1 file changed

+64
-0
lines changed

packages/react-reconciler/src/__tests__/ReactIncrementalUpdates-test.internal.js

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -653,4 +653,68 @@ describe('ReactIncrementalUpdates', () => {
653653
expect(Scheduler).toFlushAndYield(['Commit: goodbye']);
654654
});
655655
});
656+
657+
it('when rebasing, does not exclude updates that were already committed, regardless of priority', async () => {
658+
const {useState, useLayoutEffect} = React;
659+
660+
let pushToLog;
661+
function App() {
662+
const [log, setLog] = useState('');
663+
pushToLog = msg => {
664+
setLog(prevLog => prevLog + msg);
665+
};
666+
667+
useLayoutEffect(
668+
() => {
669+
Scheduler.unstable_yieldValue('Committed: ' + log);
670+
if (log === 'B') {
671+
// Right after B commits, schedule additional updates.
672+
Scheduler.unstable_runWithPriority(
673+
Scheduler.unstable_UserBlockingPriority,
674+
() => {
675+
pushToLog('C');
676+
},
677+
);
678+
setLog(prevLog => prevLog + 'D');
679+
}
680+
},
681+
[log],
682+
);
683+
684+
return log;
685+
}
686+
687+
const root = ReactNoop.createRoot();
688+
await ReactNoop.act(async () => {
689+
root.render(<App />);
690+
});
691+
expect(Scheduler).toHaveYielded(['Committed: ']);
692+
expect(root).toMatchRenderedOutput('');
693+
694+
await ReactNoop.act(async () => {
695+
pushToLog('A');
696+
Scheduler.unstable_runWithPriority(
697+
Scheduler.unstable_UserBlockingPriority,
698+
() => {
699+
pushToLog('B');
700+
},
701+
);
702+
});
703+
expect(Scheduler).toHaveYielded([
704+
// A and B are pending. B is higher priority, so we'll render that first.
705+
'Committed: B',
706+
// Because A comes first in the queue, we're now in rebase mode. B must
707+
// be rebased on top of A. Also, in a layout effect, we received two new
708+
// updates: C and D. C is user-blocking and D is synchronous.
709+
//
710+
// First render the synchronous update. What we're testing here is that
711+
// B *is not dropped* even though it has lower than sync priority. That's
712+
// because we already committed it. However, this render should not
713+
// include C, because that update wasn't already committed.
714+
'Committed: BD',
715+
'Committed: BCD',
716+
'Committed: ABCD',
717+
]);
718+
expect(root).toMatchRenderedOutput('ABCD');
719+
});
656720
});

0 commit comments

Comments
 (0)