45
isSubsetOfLanes,
46
mergeLanes,
47
removeLanes,
48
+ intersectLanes,
49
+ isTransitionLane,
50
markRootEntangled,
51
markRootMutableRead,
52
getCurrentUpdateLanePriority,
106
import {logStateUpdateScheduled} from './DebugTracing';
107
import {markStateUpdateScheduled} from './SchedulingProfiler';
108
import {CacheContext} from './ReactFiberCacheComponent.new';
107
-import {createUpdate, enqueueUpdate} from './ReactUpdateQueue.new';
109
+import {
110
+ createUpdate,
111
+ enqueueUpdate,
112
+ entangleTransitions,
113
+} from './ReactUpdateQueue.new';
114
import {pushInterleavedQueue} from './ReactFiberInterleavedUpdates.new';
115
116
const {ReactCurrentDispatcher, ReactCurrentBatchConfig} = ReactSharedInternals;
127
export type UpdateQueue<S, A> = {|
128
pending: Update<S, A> | null,
129
interleaved: Update<S, A> | null,
130
+ lanes: Lanes,
131
dispatch: (A => mixed) | null,
132
lastRenderedReducer: ((S, A) => S) | null,
133
lastRenderedState: S | null,
661
const queue = (hook.queue = {
662
pending: null,
663
interleaved: null,
664
+ lanes: NoLanes,
665
dispatch: null,
666
lastRenderedReducer: reducer,
667
lastRenderedState: (initialState: any),
819
markSkippedUpdateLanes(interleavedLane);
820
interleaved = ((interleaved: any).next: Update<S, A>);
821
} while (interleaved !== lastInterleaved);
822
+ } else if (baseQueue === null) {
823
+ // `queue.lanes` is used for entangling transitions. We can set it back to
824
+ // zero once the queue is empty.
825
+ queue.lanes = NoLanes;
826
}
827
828
const dispatch: Dispatch<A> = (queue.dispatch: any);
1114
const newQueue = {
1115
pending: null,
1116
interleaved: null,
1117
+ lanes: NoLanes,
1118
dispatch: null,
1119
lastRenderedReducer: basicStateReducer,
1120
lastRenderedState: snapshot,
1171
const queue = (hook.queue = {
1172
pending: null,
1173
interleaved: null,
1174
+ lanes: NoLanes,
1175
dispatch: null,
1176
lastRenderedReducer: basicStateReducer,
1177
lastRenderedState: (initialState: any),
1835
const lane = requestUpdateLane(provider);
1836
const eventTime = requestEventTime();
1837
const root = scheduleUpdateOnFiber(provider, lane, eventTime);
1838
+ if (root !== null) {
1839
+ entangleTransitions(root, fiber, lane);
1840
+ }
1841
1842
const seededCache = new Map();
1843
if (seedKey !== null && seedKey !== undefined && root !== null) {
1977
warnIfNotCurrentlyActingUpdatesInDev(fiber);
1978
}
1979
}
1963
- scheduleUpdateOnFiber(fiber, lane, eventTime);
1980
+ const root = scheduleUpdateOnFiber(fiber, lane, eventTime);
1981
+
1982
+ if (isTransitionLane(lane) && root !== null) {
1983
+ let queueLanes = queue.lanes;
1984
+
1985
+ // If any entangled lanes are no longer pending on the root, then they
1986
+ // must have finished. We can remove them from the shared queue, which
1987
+ // represents a superset of the actually pending lanes. In some cases we
1988
+ // may entangle more than we need to, but that's OK. In fact it's worse if
1989
+ // we *don't* entangle when we should.
1990
+ queueLanes = intersectLanes(queueLanes, root.pendingLanes);
1991
+
1992
+ // Entangle the new transition lane with the other transition lanes.
1993
+ const newQueueLanes = mergeLanes(queueLanes, lane);
1994
+ if (newQueueLanes !== queueLanes) {
1995
+ queue.lanes = newQueueLanes;
1996
+ markRootEntangled(root, newQueueLanes);
1997
+ }
1998
+ }
1999
}
2000
2001
if (__DEV__) {