Skip to content

Commit

Permalink
refactors the currentUpdatePriority apis to more clearly communicate …
Browse files Browse the repository at this point in the history
…when you are reading a raw value and when you are getting a resolved value. This allows requestUpdateLane to do a single call into the renderer to get the update priority while still making a reasonable stack based updating of update priorities ergonomic. I had to expose a `peekCurrentUpdatePriority` to satisfy startTransition which needs to set a new priority only if the current one is too low. I tried to stay away from get/set naming to avoid potential issues with whether you are reading the raw value or the derived one that considers window.event
  • Loading branch information
gnoff committed Apr 5, 2024
1 parent 2a00183 commit a6219fd
Show file tree
Hide file tree
Showing 15 changed files with 129 additions and 108 deletions.
12 changes: 8 additions & 4 deletions packages/react-art/src/ReactFiberConfigART.js
Original file line number Diff line number Diff line change
Expand Up @@ -343,16 +343,20 @@ export function shouldSetTextContent(type, props) {

let currentUpdatePriority: EventPriority = NoEventPriority;

export function setCurrentUpdatePriority(newPriority: EventPriority) {
export function swapCurrentUpdatePriority(
newPriority: EventPriority,
): EventPriority {
const prevPriority = currentUpdatePriority;
currentUpdatePriority = newPriority;
return prevPriority;
}

export function getCurrentUpdatePriority() {
export function peekCurrentUpdatePriority(): EventPriority {
return currentUpdatePriority;
}

export function getCurrentEventPriority() {
return DefaultEventPriority;
export function resolveUpdatePriority(): EventPriority {
return currentUpdatePriority || DefaultEventPriority;
}

export function shouldAttemptEagerTransition() {
Expand Down
31 changes: 26 additions & 5 deletions packages/react-dom-bindings/src/client/ReactDOMUpdatePriority.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,24 +9,45 @@

import type {EventPriority} from 'react-reconciler/src/ReactEventPriorities';

import {getEventPriority} from '../events/ReactDOMEventListener';
import {
NoEventPriority,
DefaultEventPriority,
} from 'react-reconciler/src/ReactEventPriorities';

import ReactDOMSharedInternals from 'shared/ReactDOMSharedInternals';
const ReactDOMCurrentUpdatePriority =
ReactDOMSharedInternals.ReactDOMCurrentUpdatePriority;

export function setCurrentUpdatePriority(newPriority: EventPriority): void {
export function swapCurrentUpdatePriority(
newPriority: EventPriority,
): EventPriority {
const current = ReactDOMCurrentUpdatePriority.current;
ReactDOMCurrentUpdatePriority.current = newPriority;
return current;
}

export function getCurrentUpdatePriority(): EventPriority {
export function peekCurrentUpdatePriority(): EventPriority {
return ReactDOMCurrentUpdatePriority.current;
}

export function resolveUpdatePriority(): EventPriority {
const updatePriority = ReactDOMCurrentUpdatePriority.current;
if (updatePriority !== NoEventPriority) {
return updatePriority;
}
const currentEvent = window.event;
if (currentEvent === undefined) {
return DefaultEventPriority;
}
return getEventPriority(currentEvent.type);
}

export function runWithPriority<T>(priority: EventPriority, fn: () => T): T {
const previousPriority = getCurrentUpdatePriority();
const previousPriority = swapCurrentUpdatePriority(priority);
try {
setCurrentUpdatePriority(priority);
return fn();
} finally {
setCurrentUpdatePriority(previousPriority);
swapCurrentUpdatePriority(previousPriority);
}
}
16 changes: 3 additions & 13 deletions packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
* @flow
*/

import type {EventPriority} from 'react-reconciler/src/ReactEventPriorities';
import type {DOMEventName} from '../events/DOMEventNames';
import type {Fiber, FiberRoot} from 'react-reconciler/src/ReactInternalTypes';
import type {
Expand All @@ -29,14 +28,14 @@ import type {

import {NotPending} from 'react-dom-bindings/src/shared/ReactDOMFormActions';
import {getCurrentRootHostContainer} from 'react-reconciler/src/ReactFiberHostContext';
import {DefaultEventPriority} from 'react-reconciler/src/ReactEventPriorities';

import hasOwnProperty from 'shared/hasOwnProperty';
import {checkAttributeStringCoercion} from 'shared/CheckStringCoercion';

export {
setCurrentUpdatePriority,
getCurrentUpdatePriority,
peekCurrentUpdatePriority,
swapCurrentUpdatePriority,
resolveUpdatePriority,
} from './ReactDOMUpdatePriority';
import {
precacheFiberNode,
Expand Down Expand Up @@ -73,7 +72,6 @@ import {
import {
isEnabled as ReactBrowserEventEmitterIsEnabled,
setEnabled as ReactBrowserEventEmitterSetEnabled,
getEventPriority,
} from '../events/ReactDOMEventListener';
import {SVG_NAMESPACE, MATH_NAMESPACE} from './DOMNamespaces';
import {
Expand Down Expand Up @@ -576,14 +574,6 @@ export function createTextInstance(
return textNode;
}

export function getCurrentEventPriority(): EventPriority {
const currentEvent = window.event;
if (currentEvent === undefined) {
return DefaultEventPriority;
}
return getEventPriority(currentEvent.type);
}

let currentPopstateTransitionEvent: Event | null = null;
export function shouldAttemptEagerTransition(): boolean {
const event = window.event;
Expand Down
15 changes: 5 additions & 10 deletions packages/react-dom-bindings/src/events/ReactDOMEventListener.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,7 @@ import {
} from '../client/ReactDOMComponentTree';

import {dispatchEventForPluginEventSystem} from './DOMPluginEventSystem';
import {
getCurrentUpdatePriority,
setCurrentUpdatePriority,
} from '../client/ReactDOMUpdatePriority';
import {swapCurrentUpdatePriority} from '../client/ReactDOMUpdatePriority';

import {
getCurrentPriorityLevel as getCurrentSchedulerPriorityLevel,
Expand Down Expand Up @@ -117,14 +114,13 @@ function dispatchDiscreteEvent(
container: EventTarget,
nativeEvent: AnyNativeEvent,
) {
const previousPriority = getCurrentUpdatePriority();
const prevTransition = ReactCurrentBatchConfig.transition;
ReactCurrentBatchConfig.transition = null;
const previousPriority = swapCurrentUpdatePriority(DiscreteEventPriority);
try {
setCurrentUpdatePriority(DiscreteEventPriority);
dispatchEvent(domEventName, eventSystemFlags, container, nativeEvent);
} finally {
setCurrentUpdatePriority(previousPriority);
swapCurrentUpdatePriority(previousPriority);
ReactCurrentBatchConfig.transition = prevTransition;
}
}
Expand All @@ -135,14 +131,13 @@ function dispatchContinuousEvent(
container: EventTarget,
nativeEvent: AnyNativeEvent,
) {
const previousPriority = getCurrentUpdatePriority();
const prevTransition = ReactCurrentBatchConfig.transition;
ReactCurrentBatchConfig.transition = null;
const previousPriority = swapCurrentUpdatePriority(ContinuousEventPriority);
try {
setCurrentUpdatePriority(ContinuousEventPriority);
dispatchEvent(domEventName, eventSystemFlags, container, nativeEvent);
} finally {
setCurrentUpdatePriority(previousPriority);
swapCurrentUpdatePriority(previousPriority);
ReactCurrentBatchConfig.transition = prevTransition;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ import {isHigherEventPriority} from 'react-reconciler/src/ReactEventPriorities';
import {isRootDehydrated} from 'react-reconciler/src/ReactFiberShellHydration';
import {dispatchReplayedFormAction} from './plugins/FormActionEventPlugin';
import {
getCurrentUpdatePriority,
peekCurrentUpdatePriority,
runWithPriority as attemptHydrationAtPriority,
} from '../client/ReactDOMUpdatePriority';

Expand Down Expand Up @@ -336,7 +336,7 @@ export function queueExplicitHydrationTarget(target: Node): void {
// TODO: This will read the priority if it's dispatched by the React
// event system but not native events. Should read window.event.type, like
// we do for updates (getCurrentEventPriority).
const updatePriority = getCurrentUpdatePriority();
const updatePriority = peekCurrentUpdatePriority();
const queuedTarget: QueuedHydrationTarget = {
blockedOn: null,
target: target,
Expand Down
18 changes: 12 additions & 6 deletions packages/react-native-renderer/src/ReactFiberConfigFabric.js
Original file line number Diff line number Diff line change
Expand Up @@ -313,17 +313,23 @@ export function shouldSetTextContent(type: string, props: Props): boolean {
}

let currentUpdatePriority: EventPriority = NoEventPriority;
export function setCurrentUpdatePriority(
newEventPriority: EventPriority,
): void {
currentUpdatePriority = newEventPriority;
export function swapCurrentUpdatePriority(
newPriority: EventPriority,
): EventPriority {
const previousPriority = currentUpdatePriority;
currentUpdatePriority = newPriority;
return previousPriority;
}

export function getCurrentUpdatePriority(): EventPriority {
export function peekCurrentUpdatePriority(): EventPriority {
return currentUpdatePriority;
}

export function getCurrentEventPriority(): EventPriority {
export function resolveUpdatePriority(): EventPriority {
if (currentUpdatePriority !== NoEventPriority) {
return currentUpdatePriority;
}

const currentEventPriority = fabricGetCurrentEventPriority
? fabricGetCurrentEventPriority()
: null;
Expand Down
13 changes: 10 additions & 3 deletions packages/react-native-renderer/src/ReactFiberConfigNative.js
Original file line number Diff line number Diff line change
Expand Up @@ -255,15 +255,22 @@ export function shouldSetTextContent(type: string, props: Props): boolean {
}

let currentUpdatePriority: EventPriority = NoEventPriority;
export function setCurrentUpdatePriority(newPriority: EventPriority): void {
export function swapCurrentUpdatePriority(
newPriority: EventPriority,
): EventPriority {
const previousPriority = currentUpdatePriority;
currentUpdatePriority = newPriority;
return previousPriority;
}

export function getCurrentUpdatePriority(): EventPriority {
export function peekCurrentUpdatePriority(): EventPriority {
return currentUpdatePriority;
}

export function getCurrentEventPriority(): EventPriority {
export function resolveUpdatePriority(): EventPriority {
if (currentUpdatePriority !== NoEventPriority) {
return currentUpdatePriority;
}
return DefaultEventPriority;
}

Expand Down
22 changes: 14 additions & 8 deletions packages/react-noop-renderer/src/createReactNoop.js
Original file line number Diff line number Diff line change
Expand Up @@ -510,10 +510,13 @@ function createReactNoop(reconciler: Function, useMutation: boolean) {

resetAfterCommit(): void {},

setCurrentUpdatePriority,
getCurrentUpdatePriority,
swapCurrentUpdatePriority,
peekCurrentUpdatePriority,

getCurrentEventPriority() {
resolveUpdatePriority() {
if (currentUpdatePriority !== NoEventPriority) {
return currentUpdatePriority;
}
return currentEventPriority;
},

Expand Down Expand Up @@ -788,11 +791,15 @@ function createReactNoop(reconciler: Function, useMutation: boolean) {
const DEFAULT_ROOT_ID = '<default>';

let currentUpdatePriority = NoEventPriority;
function setCurrentUpdatePriority(newPriority: EventPriority): void {
function swapCurrentUpdatePriority(
newPriority: EventPriority,
): EventPriority {
const previousPriority = currentUpdatePriority;
currentUpdatePriority = newPriority;
return previousPriority;
}

function getCurrentUpdatePriority(): EventPriority {
function peekCurrentUpdatePriority(): EventPriority {
return currentUpdatePriority;
}

Expand Down Expand Up @@ -1229,12 +1236,11 @@ function createReactNoop(reconciler: Function, useMutation: boolean) {
priority: EventPriority,
fn: () => T,
): T {
const previousPriority = getCurrentUpdatePriority();
const previousPriority = swapCurrentUpdatePriority(priority);
try {
setCurrentUpdatePriority(priority);
return fn();
} finally {
setCurrentUpdatePriority(previousPriority);
swapCurrentUpdatePriority(previousPriority);
}
},

Expand Down
4 changes: 4 additions & 0 deletions packages/react-reconciler/src/ReactEventPriorities.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ export function isHigherEventPriority(
return a !== 0 && a < b;
}

export function eventPriorityToLane(updatePriority: EventPriority): Lane {
return updatePriority;
}

export function lanesToEventPriority(lanes: Lanes): EventPriority {
const lane = getHighestPriorityLane(lanes);
if (!isHigherEventPriority(DiscreteEventPriority, lane)) {
Expand Down
10 changes: 5 additions & 5 deletions packages/react-reconciler/src/ReactFiberHooks.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ import type {TransitionStatus} from './ReactFiberConfig';

import {
NotPendingTransition as NoPendingHostTransition,
setCurrentUpdatePriority,
getCurrentUpdatePriority,
swapCurrentUpdatePriority,
peekCurrentUpdatePriority,
} from './ReactFiberConfig';
import ReactSharedInternals from 'shared/ReactSharedInternals';
import {
Expand Down Expand Up @@ -2790,8 +2790,8 @@ function startTransition<S>(
callback: () => mixed,
options?: StartTransitionOptions,
): void {
const previousPriority = getCurrentUpdatePriority();
setCurrentUpdatePriority(
const previousPriority = peekCurrentUpdatePriority();
swapCurrentUpdatePriority(
higherEventPriority(previousPriority, ContinuousEventPriority),
);

Expand Down Expand Up @@ -2877,7 +2877,7 @@ function startTransition<S>(
throw error;
}
} finally {
setCurrentUpdatePriority(previousPriority);
swapCurrentUpdatePriority(previousPriority);

ReactCurrentBatchConfig.transition = prevTransition;

Expand Down
4 changes: 1 addition & 3 deletions packages/react-reconciler/src/ReactFiberReconciler.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ import getComponentNameFromFiber from 'react-reconciler/src/getComponentNameFrom
import isArray from 'shared/isArray';
import {enableSchedulingProfiler} from 'shared/ReactFeatureFlags';
import ReactSharedInternals from 'shared/ReactSharedInternals';
import {getPublicInstance, getCurrentUpdatePriority} from './ReactFiberConfig';
import {getPublicInstance} from './ReactFiberConfig';
import {
findCurrentUnmaskedContext,
processChildContext,
Expand Down Expand Up @@ -521,8 +521,6 @@ export function attemptHydrationAtCurrentPriority(fiber: Fiber): void {
markRetryLaneIfNotHydrated(fiber, lane);
}

export {getCurrentUpdatePriority};

export {findHostInstance};

export {findHostInstanceWithWarning};
Expand Down
Loading

0 comments on commit a6219fd

Please sign in to comment.