diff --git a/packages/react-reconciler/src/ReactFiberExpirationTime.js b/packages/react-reconciler/src/ReactFiberExpirationTime.js
index e28e888545a29..a8594a57a3fe6 100644
--- a/packages/react-reconciler/src/ReactFiberExpirationTime.js
+++ b/packages/react-reconciler/src/ReactFiberExpirationTime.js
@@ -111,14 +111,14 @@ export function inferPriorityFromExpirationTime(
return IdlePriority;
}
const msUntil =
- msToExpirationTime(expirationTime) - msToExpirationTime(currentTime);
+ expirationTimeToMs(expirationTime) - expirationTimeToMs(currentTime);
if (msUntil <= 0) {
return ImmediatePriority;
}
- if (msUntil <= HIGH_PRIORITY_EXPIRATION) {
+ if (msUntil <= HIGH_PRIORITY_EXPIRATION + HIGH_PRIORITY_BATCH_SIZE) {
return UserBlockingPriority;
}
- if (msUntil <= LOW_PRIORITY_EXPIRATION) {
+ if (msUntil <= LOW_PRIORITY_EXPIRATION + LOW_PRIORITY_BATCH_SIZE) {
return NormalPriority;
}
diff --git a/packages/react-reconciler/src/__tests__/ReactSchedulerIntegration-test.internal.js b/packages/react-reconciler/src/__tests__/ReactSchedulerIntegration-test.internal.js
index d558a578a20b5..dec4bfbfc57b1 100644
--- a/packages/react-reconciler/src/__tests__/ReactSchedulerIntegration-test.internal.js
+++ b/packages/react-reconciler/src/__tests__/ReactSchedulerIntegration-test.internal.js
@@ -150,6 +150,22 @@ describe('ReactSchedulerIntegration', () => {
]);
});
+ it('after completing a level of work, infers priority of the next batch based on its expiration time', () => {
+ function App({label}) {
+ Scheduler.yieldValue(`${label} [${getCurrentPriorityAsString()}]`);
+ return label;
+ }
+
+ // Schedule two separate updates at different priorities
+ runWithPriority(UserBlockingPriority, () => {
+ ReactNoop.render();
+ });
+ ReactNoop.render();
+
+ // The second update should run at normal priority
+ expect(Scheduler).toFlushAndYield(['A [UserBlocking]', 'B [Normal]']);
+ });
+
// TODO
it.skip('passive effects have render priority even if they are flushed early', () => {});
});