Skip to content

Commit bd9672d

Browse files
committed
Use callback priority to determine cancellation
1 parent bf6990a commit bd9672d

File tree

3 files changed

+38
-19
lines changed

3 files changed

+38
-19
lines changed

packages/react-reconciler/src/ReactFiberWorkLoop.new.js

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -716,21 +716,27 @@ function ensureRootIsScheduled(root: FiberRoot, currentTime: number) {
716716
// Special case: There's nothing to work on.
717717
if (existingCallbackNode !== null) {
718718
cancelCallback(existingCallbackNode);
719-
root.callbackNode = null;
720-
root.callbackPriority = NoLanePriority;
721719
}
720+
root.callbackNode = null;
721+
root.callbackPriority = NoLanePriority;
722722
return;
723723
}
724724

725725
// Check if there's an existing task. We may be able to reuse it.
726-
if (existingCallbackNode !== null) {
727-
const existingCallbackPriority = root.callbackPriority;
728-
if (existingCallbackPriority === newCallbackPriority) {
729-
// The priority hasn't changed. We can reuse the existing task. Exit.
730-
return;
726+
const existingCallbackPriority = root.callbackPriority;
727+
if (existingCallbackPriority === newCallbackPriority) {
728+
if (__DEV__) {
729+
invariant(
730+
existingCallbackNode,
731+
'Expected scheduled callback to exist. This error is likely caused by a bug in React. Please file an issue.',
732+
);
731733
}
732-
// The priority changed. Cancel the existing callback. We'll schedule a new
733-
// one below.
734+
// The priority hasn't changed. We can reuse the existing task. Exit.
735+
return;
736+
}
737+
738+
if (existingCallbackNode != null) {
739+
// Cancel the existing callback. We'll schedule a new one below.
734740
cancelCallback(existingCallbackNode);
735741
}
736742

@@ -739,6 +745,8 @@ function ensureRootIsScheduled(root: FiberRoot, currentTime: number) {
739745
if (newCallbackPriority === SyncLanePriority) {
740746
// Special case: Sync React callbacks are scheduled on a special
741747
// internal queue
748+
749+
// TODO: After enableDiscreteEventMicroTasks lands, we can remove the fake node.
742750
newCallbackNode = scheduleSyncCallback(
743751
performSyncWorkOnRoot.bind(null, root),
744752
);
@@ -1879,6 +1887,7 @@ function commitRootImpl(root, renderPriorityLevel) {
18791887
// commitRoot never returns a continuation; it always finishes synchronously.
18801888
// So we can clear these now to allow a new callback to be scheduled.
18811889
root.callbackNode = null;
1890+
root.callbackPriority = NoLanePriority;
18821891

18831892
// Update the first and last pending times on this root. The new first
18841893
// pending time is whatever is left on the root fiber.

packages/react-reconciler/src/ReactFiberWorkLoop.old.js

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -698,21 +698,27 @@ function ensureRootIsScheduled(root: FiberRoot, currentTime: number) {
698698
// Special case: There's nothing to work on.
699699
if (existingCallbackNode !== null) {
700700
cancelCallback(existingCallbackNode);
701-
root.callbackNode = null;
702-
root.callbackPriority = NoLanePriority;
703701
}
702+
root.callbackNode = null;
703+
root.callbackPriority = NoLanePriority;
704704
return;
705705
}
706706

707707
// Check if there's an existing task. We may be able to reuse it.
708-
if (existingCallbackNode !== null) {
709-
const existingCallbackPriority = root.callbackPriority;
710-
if (existingCallbackPriority === newCallbackPriority) {
711-
// The priority hasn't changed. We can reuse the existing task. Exit.
712-
return;
708+
const existingCallbackPriority = root.callbackPriority;
709+
if (existingCallbackPriority === newCallbackPriority) {
710+
if (__DEV__) {
711+
invariant(
712+
existingCallbackNode,
713+
'Expected scheduled callback to exist. This error is likely caused by a bug in React. Please file an issue.',
714+
);
713715
}
714-
// The priority changed. Cancel the existing callback. We'll schedule a new
715-
// one below.
716+
// The priority hasn't changed. We can reuse the existing task. Exit.
717+
return;
718+
}
719+
720+
if (existingCallbackNode != null) {
721+
// Cancel the existing callback. We'll schedule a new one below.
716722
cancelCallback(existingCallbackNode);
717723
}
718724

@@ -721,6 +727,8 @@ function ensureRootIsScheduled(root: FiberRoot, currentTime: number) {
721727
if (newCallbackPriority === SyncLanePriority) {
722728
// Special case: Sync React callbacks are scheduled on a special
723729
// internal queue
730+
731+
// TODO: After enableDiscreteEventMicroTasks lands, we can remove the fake node.
724732
newCallbackNode = scheduleSyncCallback(
725733
performSyncWorkOnRoot.bind(null, root),
726734
);
@@ -1859,6 +1867,7 @@ function commitRootImpl(root, renderPriorityLevel) {
18591867
// commitRoot never returns a continuation; it always finishes synchronously.
18601868
// So we can clear these now to allow a new callback to be scheduled.
18611869
root.callbackNode = null;
1870+
root.callbackPriority = NoLanePriority;
18621871

18631872
// Update the first and last pending times on this root. The new first
18641873
// pending time is whatever is left on the root fiber.

scripts/error-codes/codes.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -372,5 +372,6 @@
372372
"381": "This feature is not supported by ReactSuspenseTestUtils.",
373373
"382": "This query has received more parameters than the last time the same query was used. Always pass the exact number of parameters that the query needs.",
374374
"383": "This query has received fewer parameters than the last time the same query was used. Always pass the exact number of parameters that the query needs.",
375-
"384": "Refreshing the cache is not supported in Server Components."
375+
"384": "Refreshing the cache is not supported in Server Components.",
376+
"385": "Expected scheduled callback to exist. This error is likely caused by a bug in React. Please file an issue."
376377
}

0 commit comments

Comments
 (0)