mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
Set current update lane priority for user blocking events (#19342)
* Set current update lane priority for user blocking events * Update to use LanePriority and not use runWithPriority * Remove unused imports * Fix tests, and I missed ReactDOMEventListener * Fix more tests * Add try/finally and hardcode lane priorities instead * Also hard code InputContinuousLanePriority in tests * Remove un-needed exports * Comment rollbacks
This commit is contained in:
+2
-2
@@ -36,7 +36,7 @@ import {
|
||||
attemptContinuousHydration,
|
||||
attemptHydrationAtCurrentPriority,
|
||||
runWithPriority,
|
||||
getCurrentUpdatePriority,
|
||||
getCurrentUpdateLanePriority,
|
||||
} from 'react-reconciler/src/ReactFiberReconciler';
|
||||
import {createPortal as createPortalImpl} from 'react-reconciler/src/ReactPortal';
|
||||
import {canUseDOM} from 'shared/ExecutionEnvironment';
|
||||
@@ -74,7 +74,7 @@ setAttemptSynchronousHydration(attemptSynchronousHydration);
|
||||
setAttemptUserBlockingHydration(attemptUserBlockingHydration);
|
||||
setAttemptContinuousHydration(attemptContinuousHydration);
|
||||
setAttemptHydrationAtCurrentPriority(attemptHydrationAtCurrentPriority);
|
||||
setGetCurrentUpdatePriority(getCurrentUpdatePriority);
|
||||
setGetCurrentUpdatePriority(getCurrentUpdateLanePriority);
|
||||
setAttemptHydrationAtPriority(runWithPriority);
|
||||
|
||||
let didWarnAboutUnstableCreatePortal = false;
|
||||
|
||||
@@ -56,6 +56,13 @@ import {
|
||||
// Intentionally not named imports because Rollup would use dynamic dispatch for
|
||||
// CommonJS interop named imports.
|
||||
import * as Scheduler from 'scheduler';
|
||||
|
||||
import {
|
||||
InputContinuousLanePriority,
|
||||
getCurrentUpdateLanePriority,
|
||||
setCurrentUpdateLanePriority,
|
||||
} from 'react-reconciler/src/ReactFiberLane';
|
||||
|
||||
const {
|
||||
unstable_UserBlockingPriority: UserBlockingPriority,
|
||||
unstable_runWithPriority: runWithPriority,
|
||||
@@ -101,9 +108,15 @@ const eventResponderContext: ReactDOMResponderContext = {
|
||||
break;
|
||||
}
|
||||
case UserBlockingEvent: {
|
||||
runWithPriority(UserBlockingPriority, () =>
|
||||
executeUserEventHandler(eventListener, eventValue),
|
||||
);
|
||||
const previousPriority = getCurrentUpdateLanePriority();
|
||||
try {
|
||||
setCurrentUpdateLanePriority(InputContinuousLanePriority);
|
||||
runWithPriority(UserBlockingPriority, () =>
|
||||
executeUserEventHandler(eventListener, eventValue),
|
||||
);
|
||||
} finally {
|
||||
setCurrentUpdateLanePriority(previousPriority);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ContinuousEvent: {
|
||||
|
||||
+22
-10
@@ -56,6 +56,11 @@ import {
|
||||
flushDiscreteUpdatesIfNeeded,
|
||||
discreteUpdates,
|
||||
} from './ReactDOMUpdateBatching';
|
||||
import {
|
||||
InputContinuousLanePriority,
|
||||
getCurrentUpdateLanePriority,
|
||||
setCurrentUpdateLanePriority,
|
||||
} from 'react-reconciler/src/ReactFiberLane';
|
||||
|
||||
const {
|
||||
unstable_UserBlockingPriority: UserBlockingPriority,
|
||||
@@ -148,16 +153,23 @@ function dispatchUserBlockingUpdate(
|
||||
container,
|
||||
nativeEvent,
|
||||
) {
|
||||
runWithPriority(
|
||||
UserBlockingPriority,
|
||||
dispatchEvent.bind(
|
||||
null,
|
||||
topLevelType,
|
||||
eventSystemFlags,
|
||||
container,
|
||||
nativeEvent,
|
||||
),
|
||||
);
|
||||
// TODO: Double wrapping is necessary while we decouple Scheduler priority.
|
||||
const previousPriority = getCurrentUpdateLanePriority();
|
||||
try {
|
||||
setCurrentUpdateLanePriority(InputContinuousLanePriority);
|
||||
runWithPriority(
|
||||
UserBlockingPriority,
|
||||
dispatchEvent.bind(
|
||||
null,
|
||||
topLevelType,
|
||||
eventSystemFlags,
|
||||
container,
|
||||
nativeEvent,
|
||||
),
|
||||
);
|
||||
} finally {
|
||||
setCurrentUpdateLanePriority(previousPriority);
|
||||
}
|
||||
}
|
||||
|
||||
export function dispatchEvent(
|
||||
|
||||
+7
-12
@@ -12,10 +12,8 @@ import type {Container, SuspenseInstance} from '../client/ReactDOMHostConfig';
|
||||
import type {DOMTopLevelEventType} from '../events/TopLevelEventTypes';
|
||||
import type {ElementListenerMap} from '../client/ReactDOMComponentTree';
|
||||
import type {EventSystemFlags} from './EventSystemFlags';
|
||||
import type {
|
||||
FiberRoot,
|
||||
ReactPriorityLevel,
|
||||
} from 'react-reconciler/src/ReactInternalTypes';
|
||||
import type {FiberRoot} from 'react-reconciler/src/ReactInternalTypes';
|
||||
import type {LanePriority} from 'react-reconciler/src/ReactFiberLane';
|
||||
|
||||
import {
|
||||
enableDeprecatedFlareAPI,
|
||||
@@ -67,19 +65,16 @@ export function setAttemptHydrationAtCurrentPriority(
|
||||
attemptHydrationAtCurrentPriority = fn;
|
||||
}
|
||||
|
||||
let getCurrentUpdatePriority: () => ReactPriorityLevel;
|
||||
let getCurrentUpdatePriority: () => LanePriority;
|
||||
|
||||
export function setGetCurrentUpdatePriority(fn: () => ReactPriorityLevel) {
|
||||
export function setGetCurrentUpdatePriority(fn: () => LanePriority) {
|
||||
getCurrentUpdatePriority = fn;
|
||||
}
|
||||
|
||||
let attemptHydrationAtPriority: <T>(
|
||||
priority: ReactPriorityLevel,
|
||||
fn: () => T,
|
||||
) => T;
|
||||
let attemptHydrationAtPriority: <T>(priority: LanePriority, fn: () => T) => T;
|
||||
|
||||
export function setAttemptHydrationAtPriority(
|
||||
fn: <T>(priority: ReactPriorityLevel, fn: () => T) => T,
|
||||
fn: <T>(priority: LanePriority, fn: () => T) => T,
|
||||
) {
|
||||
attemptHydrationAtPriority = fn;
|
||||
}
|
||||
@@ -170,7 +165,7 @@ type QueuedHydrationTarget = {|
|
||||
blockedOn: null | Container | SuspenseInstance,
|
||||
target: Node,
|
||||
priority: number,
|
||||
lanePriority: ReactPriorityLevel,
|
||||
lanePriority: LanePriority,
|
||||
|};
|
||||
const queuedExplicitHydrationTargets: Array<QueuedHydrationTarget> = [];
|
||||
|
||||
|
||||
+1
-2
@@ -47,8 +47,7 @@ export const {
|
||||
act,
|
||||
dumpTree,
|
||||
getRoot,
|
||||
// TODO: Remove this once callers migrate to alternatives.
|
||||
// This should only be used by React internals.
|
||||
// TODO: Remove this after callers migrate to alternatives.
|
||||
unstable_runWithPriority,
|
||||
} = createReactNoop(
|
||||
ReactFiberReconciler, // reconciler
|
||||
|
||||
+5
-6
@@ -51,7 +51,7 @@ import {
|
||||
observeVisibleRects as observeVisibleRects_old,
|
||||
registerMutableSourceForHydration as registerMutableSourceForHydration_old,
|
||||
runWithPriority as runWithPriority_old,
|
||||
getCurrentUpdatePriority as getCurrentUpdatePriority_old,
|
||||
getCurrentUpdateLanePriority as getCurrentUpdateLanePriority_old,
|
||||
} from './ReactFiberReconciler.old';
|
||||
|
||||
import {
|
||||
@@ -91,7 +91,7 @@ import {
|
||||
observeVisibleRects as observeVisibleRects_new,
|
||||
registerMutableSourceForHydration as registerMutableSourceForHydration_new,
|
||||
runWithPriority as runWithPriority_new,
|
||||
getCurrentUpdatePriority as getCurrentUpdatePriority_new,
|
||||
getCurrentUpdateLanePriority as getCurrentUpdateLanePriority_new,
|
||||
} from './ReactFiberReconciler.new';
|
||||
|
||||
export const createContainer = enableNewReconciler
|
||||
@@ -143,9 +143,9 @@ export const attemptContinuousHydration = enableNewReconciler
|
||||
export const attemptHydrationAtCurrentPriority = enableNewReconciler
|
||||
? attemptHydrationAtCurrentPriority_new
|
||||
: attemptHydrationAtCurrentPriority_old;
|
||||
export const getCurrentUpdatePriority = enableNewReconciler
|
||||
? getCurrentUpdatePriority_new
|
||||
: getCurrentUpdatePriority_old;
|
||||
export const getCurrentUpdateLanePriority = enableNewReconciler
|
||||
? getCurrentUpdateLanePriority_new
|
||||
: getCurrentUpdateLanePriority_old;
|
||||
export const findHostInstance = enableNewReconciler
|
||||
? findHostInstance_new
|
||||
: findHostInstance_old;
|
||||
@@ -197,7 +197,6 @@ export const focusWithin = enableNewReconciler
|
||||
export const observeVisibleRects = enableNewReconciler
|
||||
? observeVisibleRects_new
|
||||
: observeVisibleRects_old;
|
||||
|
||||
export const registerMutableSourceForHydration = enableNewReconciler
|
||||
? registerMutableSourceForHydration_new
|
||||
: registerMutableSourceForHydration_old;
|
||||
|
||||
@@ -7,11 +7,7 @@
|
||||
* @flow
|
||||
*/
|
||||
|
||||
import type {
|
||||
Fiber,
|
||||
ReactPriorityLevel,
|
||||
SuspenseHydrationCallbacks,
|
||||
} from './ReactInternalTypes';
|
||||
import type {Fiber, SuspenseHydrationCallbacks} from './ReactInternalTypes';
|
||||
import type {FiberRoot} from './ReactInternalTypes';
|
||||
import type {RootTag} from './ReactRootTags';
|
||||
import type {
|
||||
@@ -23,7 +19,7 @@ import type {
|
||||
import type {RendererInspectionConfig} from './ReactFiberHostConfig';
|
||||
import {FundamentalComponent} from './ReactWorkTags';
|
||||
import type {ReactNodeList} from 'shared/ReactTypes';
|
||||
import type {Lane} from './ReactFiberLane';
|
||||
import type {Lane, LanePriority} from './ReactFiberLane';
|
||||
import type {SuspenseState} from './ReactFiberSuspenseComponent.new';
|
||||
|
||||
import {
|
||||
@@ -86,8 +82,6 @@ import {
|
||||
higherPriorityLane,
|
||||
getCurrentUpdateLanePriority,
|
||||
setCurrentUpdateLanePriority,
|
||||
schedulerPriorityToLanePriority,
|
||||
lanePriorityToSchedulerPriority,
|
||||
} from './ReactFiberLane';
|
||||
import {requestCurrentSuspenseConfig} from './ReactFiberSuspenseConfig';
|
||||
import {
|
||||
@@ -438,19 +432,17 @@ export function attemptHydrationAtCurrentPriority(fiber: Fiber): void {
|
||||
markRetryLaneIfNotHydrated(fiber, lane);
|
||||
}
|
||||
|
||||
export function runWithPriority<T>(priority: ReactPriorityLevel, fn: () => T) {
|
||||
export function runWithPriority<T>(priority: LanePriority, fn: () => T) {
|
||||
const previousPriority = getCurrentUpdateLanePriority();
|
||||
try {
|
||||
setCurrentUpdateLanePriority(schedulerPriorityToLanePriority(priority));
|
||||
setCurrentUpdateLanePriority(priority);
|
||||
return fn();
|
||||
} finally {
|
||||
setCurrentUpdateLanePriority(previousPriority);
|
||||
}
|
||||
}
|
||||
|
||||
export function getCurrentUpdatePriority(): ReactPriorityLevel {
|
||||
return lanePriorityToSchedulerPriority(getCurrentUpdateLanePriority());
|
||||
}
|
||||
export {getCurrentUpdateLanePriority};
|
||||
|
||||
export {findHostInstance};
|
||||
|
||||
|
||||
@@ -7,11 +7,7 @@
|
||||
* @flow
|
||||
*/
|
||||
|
||||
import type {
|
||||
Fiber,
|
||||
ReactPriorityLevel,
|
||||
SuspenseHydrationCallbacks,
|
||||
} from './ReactInternalTypes';
|
||||
import type {Fiber, SuspenseHydrationCallbacks} from './ReactInternalTypes';
|
||||
import type {FiberRoot} from './ReactInternalTypes';
|
||||
import type {RootTag} from './ReactRootTags';
|
||||
import type {
|
||||
@@ -23,7 +19,7 @@ import type {
|
||||
import type {RendererInspectionConfig} from './ReactFiberHostConfig';
|
||||
import {FundamentalComponent} from './ReactWorkTags';
|
||||
import type {ReactNodeList} from 'shared/ReactTypes';
|
||||
import type {Lane} from './ReactFiberLane';
|
||||
import type {Lane, LanePriority} from './ReactFiberLane';
|
||||
import type {SuspenseState} from './ReactFiberSuspenseComponent.old';
|
||||
|
||||
import {
|
||||
@@ -86,8 +82,6 @@ import {
|
||||
higherPriorityLane,
|
||||
getCurrentUpdateLanePriority,
|
||||
setCurrentUpdateLanePriority,
|
||||
schedulerPriorityToLanePriority,
|
||||
lanePriorityToSchedulerPriority,
|
||||
} from './ReactFiberLane';
|
||||
import {requestCurrentSuspenseConfig} from './ReactFiberSuspenseConfig';
|
||||
import {
|
||||
@@ -438,19 +432,17 @@ export function attemptHydrationAtCurrentPriority(fiber: Fiber): void {
|
||||
markRetryLaneIfNotHydrated(fiber, lane);
|
||||
}
|
||||
|
||||
export function runWithPriority<T>(priority: ReactPriorityLevel, fn: () => T) {
|
||||
export function runWithPriority<T>(priority: LanePriority, fn: () => T) {
|
||||
const previousPriority = getCurrentUpdateLanePriority();
|
||||
try {
|
||||
setCurrentUpdateLanePriority(schedulerPriorityToLanePriority(priority));
|
||||
setCurrentUpdateLanePriority(priority);
|
||||
return fn();
|
||||
} finally {
|
||||
setCurrentUpdateLanePriority(previousPriority);
|
||||
}
|
||||
}
|
||||
|
||||
export function getCurrentUpdatePriority(): ReactPriorityLevel {
|
||||
return lanePriorityToSchedulerPriority(getCurrentUpdateLanePriority());
|
||||
}
|
||||
export {getCurrentUpdateLanePriority};
|
||||
|
||||
export {findHostInstance};
|
||||
|
||||
|
||||
@@ -14,6 +14,11 @@ let React;
|
||||
let ReactNoop;
|
||||
let Scheduler;
|
||||
|
||||
// Copied from ReactFiberLanes. Don't do this!
|
||||
// This is hard coded directly to avoid needing to import, and
|
||||
// we'll remove this as we replace runWithPriority with React APIs.
|
||||
const InputContinuousLanePriority = 12;
|
||||
|
||||
describe('ReactIncrementalUpdates', () => {
|
||||
beforeEach(() => {
|
||||
jest.resetModuleRegistry();
|
||||
@@ -517,15 +522,13 @@ describe('ReactIncrementalUpdates', () => {
|
||||
if (log === 'B') {
|
||||
// Right after B commits, schedule additional updates.
|
||||
// TODO: Double wrapping is temporary while we remove Scheduler runWithPriority.
|
||||
ReactNoop.unstable_runWithPriority(
|
||||
Scheduler.unstable_UserBlockingPriority,
|
||||
() =>
|
||||
Scheduler.unstable_runWithPriority(
|
||||
Scheduler.unstable_UserBlockingPriority,
|
||||
() => {
|
||||
pushToLog('C');
|
||||
},
|
||||
),
|
||||
ReactNoop.unstable_runWithPriority(InputContinuousLanePriority, () =>
|
||||
Scheduler.unstable_runWithPriority(
|
||||
Scheduler.unstable_UserBlockingPriority,
|
||||
() => {
|
||||
pushToLog('C');
|
||||
},
|
||||
),
|
||||
);
|
||||
setLog(prevLog => prevLog + 'D');
|
||||
}
|
||||
@@ -545,15 +548,13 @@ describe('ReactIncrementalUpdates', () => {
|
||||
pushToLog('A');
|
||||
|
||||
// TODO: Double wrapping is temporary while we remove Scheduler runWithPriority.
|
||||
ReactNoop.unstable_runWithPriority(
|
||||
Scheduler.unstable_UserBlockingPriority,
|
||||
() =>
|
||||
Scheduler.unstable_runWithPriority(
|
||||
Scheduler.unstable_UserBlockingPriority,
|
||||
() => {
|
||||
pushToLog('B');
|
||||
},
|
||||
),
|
||||
ReactNoop.unstable_runWithPriority(InputContinuousLanePriority, () =>
|
||||
Scheduler.unstable_runWithPriority(
|
||||
Scheduler.unstable_UserBlockingPriority,
|
||||
() => {
|
||||
pushToLog('B');
|
||||
},
|
||||
),
|
||||
);
|
||||
});
|
||||
expect(Scheduler).toHaveYielded([
|
||||
@@ -586,15 +587,13 @@ describe('ReactIncrementalUpdates', () => {
|
||||
if (this.state.log === 'B') {
|
||||
// Right after B commits, schedule additional updates.
|
||||
// TODO: Double wrapping is temporary while we remove Scheduler runWithPriority.
|
||||
ReactNoop.unstable_runWithPriority(
|
||||
Scheduler.unstable_UserBlockingPriority,
|
||||
() =>
|
||||
Scheduler.unstable_runWithPriority(
|
||||
Scheduler.unstable_UserBlockingPriority,
|
||||
() => {
|
||||
this.pushToLog('C');
|
||||
},
|
||||
),
|
||||
ReactNoop.unstable_runWithPriority(InputContinuousLanePriority, () =>
|
||||
Scheduler.unstable_runWithPriority(
|
||||
Scheduler.unstable_UserBlockingPriority,
|
||||
() => {
|
||||
this.pushToLog('C');
|
||||
},
|
||||
),
|
||||
);
|
||||
this.pushToLog('D');
|
||||
}
|
||||
@@ -615,15 +614,13 @@ describe('ReactIncrementalUpdates', () => {
|
||||
await ReactNoop.act(async () => {
|
||||
pushToLog('A');
|
||||
// TODO: Double wrapping is temporary while we remove Scheduler runWithPriority.
|
||||
ReactNoop.unstable_runWithPriority(
|
||||
Scheduler.unstable_UserBlockingPriority,
|
||||
() =>
|
||||
Scheduler.unstable_runWithPriority(
|
||||
Scheduler.unstable_UserBlockingPriority,
|
||||
() => {
|
||||
pushToLog('B');
|
||||
},
|
||||
),
|
||||
ReactNoop.unstable_runWithPriority(InputContinuousLanePriority, () =>
|
||||
Scheduler.unstable_runWithPriority(
|
||||
Scheduler.unstable_UserBlockingPriority,
|
||||
() => {
|
||||
pushToLog('B');
|
||||
},
|
||||
),
|
||||
);
|
||||
});
|
||||
expect(Scheduler).toHaveYielded([
|
||||
|
||||
@@ -23,6 +23,11 @@ let onWorkScheduled;
|
||||
let onWorkStarted;
|
||||
let onWorkStopped;
|
||||
|
||||
// Copied from ReactFiberLanes. Don't do this!
|
||||
// This is hard coded directly to avoid needing to import, and
|
||||
// we'll remove this as we replace runWithPriority with React APIs.
|
||||
const IdleLanePriority = 2;
|
||||
|
||||
function loadModules() {
|
||||
ReactFeatureFlags = require('shared/ReactFeatureFlags');
|
||||
|
||||
@@ -233,13 +238,11 @@ describe('ReactDOMTracing', () => {
|
||||
} else {
|
||||
Scheduler.unstable_yieldValue('Child:mount');
|
||||
// TODO: Double wrapping is temporary while we remove Scheduler runWithPriority.
|
||||
ReactDOM.unstable_runWithPriority(
|
||||
Scheduler.unstable_IdlePriority,
|
||||
() =>
|
||||
Scheduler.unstable_runWithPriority(
|
||||
Scheduler.unstable_IdlePriority,
|
||||
() => setDidMount(true),
|
||||
),
|
||||
ReactDOM.unstable_runWithPriority(IdleLanePriority, () =>
|
||||
Scheduler.unstable_runWithPriority(
|
||||
Scheduler.unstable_IdlePriority,
|
||||
() => setDidMount(true),
|
||||
),
|
||||
);
|
||||
}
|
||||
}, [didMount]);
|
||||
|
||||
Reference in New Issue
Block a user