Skip to content

Commit 8830fd2

Browse files
committed
Store captured effects on separate list from "own" effects (callbacks)
For resuming, we need the ability to discard the "own" effects while reusing the captured effects.
1 parent 2336c85 commit 8830fd2

File tree

1 file changed

+52
-46
lines changed

1 file changed

+52
-46
lines changed

packages/react-reconciler/src/ReactUpdateQueue.js

Lines changed: 52 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,10 @@ export type UpdateQueue<State> = {
122122
firstEffect: Update<State> | null,
123123
lastEffect: Update<State> | null,
124124

125-
// TODO: Workaround for lack of tuples. Could global state instead.
125+
firstCapturedEffect: Update<State> | null,
126+
lastCapturedEffect: Update<State> | null,
127+
128+
// TODO: Workaround for lack of tuples. Could use global state instead.
126129
hasForceUpdate: boolean,
127130

128131
// DEV-only
@@ -144,6 +147,8 @@ export function createUpdateQueue<State>(baseState: State): UpdateQueue<State> {
144147
lastCapturedUpdate: null,
145148
firstEffect: null,
146149
lastEffect: null,
150+
firstCapturedEffect: null,
151+
lastCapturedEffect: null,
147152
hasForceUpdate: false,
148153
};
149154
if (__DEV__) {
@@ -170,6 +175,9 @@ function cloneUpdateQueue<State>(
170175

171176
firstEffect: null,
172177
lastEffect: null,
178+
179+
firstCapturedEffect: null,
180+
lastCapturedEffect: null,
173181
};
174182
if (__DEV__) {
175183
queue.isProcessing = false;
@@ -330,39 +338,6 @@ export function enqueueCapturedUpdate<State>(
330338
}
331339
}
332340

333-
function addToEffectList<State>(
334-
queue: UpdateQueue<State>,
335-
update: Update<State>,
336-
) {
337-
// Set this to null, in case it was mutated during an aborted render.
338-
update.nextEffect = null;
339-
if (queue.lastEffect === null) {
340-
queue.firstEffect = queue.lastEffect = update;
341-
} else {
342-
queue.lastEffect.nextEffect = update;
343-
queue.lastEffect = update;
344-
}
345-
}
346-
347-
function processSingleUpdate<State>(
348-
workInProgress: Fiber,
349-
queue: UpdateQueue<State>,
350-
update: Update<State>,
351-
prevState: State,
352-
): State {
353-
const commit = update.commit;
354-
const process = update.process;
355-
if (commit !== null) {
356-
workInProgress.effectTag |= Callback;
357-
addToEffectList(queue, update);
358-
}
359-
if (process !== null) {
360-
return process(workInProgress, prevState, queue);
361-
} else {
362-
return prevState;
363-
}
364-
}
365-
366341
function ensureWorkInProgressQueueIsAClone<State>(
367342
workInProgress: Fiber,
368343
queue: UpdateQueue<State>,
@@ -428,12 +403,22 @@ export function processUpdateQueue<State>(
428403
} else {
429404
// This update does have sufficient priority. Process it and compute
430405
// a new result.
431-
resultState = processSingleUpdate(
432-
workInProgress,
433-
queue,
434-
update,
435-
resultState,
436-
);
406+
const commit = update.commit;
407+
const process = update.process;
408+
if (process !== null) {
409+
resultState = process(workInProgress, resultState, queue);
410+
}
411+
if (commit !== null) {
412+
workInProgress.effectTag |= Callback;
413+
// Set this to null, in case it was mutated during an aborted render.
414+
update.nextEffect = null;
415+
if (queue.lastEffect === null) {
416+
queue.firstEffect = queue.lastEffect = update;
417+
} else {
418+
queue.lastEffect.nextEffect = update;
419+
queue.lastEffect = update;
420+
}
421+
}
437422
}
438423
// Continue to the next update.
439424
update = update.next;
@@ -467,12 +452,22 @@ export function processUpdateQueue<State>(
467452
} else {
468453
// This update does have sufficient priority. Process it and compute
469454
// a new result.
470-
resultState = processSingleUpdate(
471-
workInProgress,
472-
queue,
473-
update,
474-
resultState,
475-
);
455+
const commit = update.commit;
456+
const process = update.process;
457+
if (process !== null) {
458+
resultState = process(workInProgress, resultState, queue);
459+
}
460+
if (commit !== null) {
461+
workInProgress.effectTag |= Callback;
462+
// Set this to null, in case it was mutated during an aborted render.
463+
update.nextEffect = null;
464+
if (queue.lastCapturedEffect === null) {
465+
queue.firstCapturedEffect = queue.lastCapturedEffect = update;
466+
} else {
467+
queue.lastCapturedEffect.nextEffect = update;
468+
queue.lastCapturedEffect = update;
469+
}
470+
}
476471
}
477472
update = update.next;
478473
}
@@ -533,4 +528,15 @@ export function commitUpdateQueue<State>(
533528
}
534529
effect = effect.nextEffect;
535530
}
531+
532+
effect = finishedQueue.firstCapturedEffect;
533+
finishedQueue.firstCapturedEffect = finishedQueue.lastCapturedEffect = null;
534+
while (effect !== null) {
535+
const commit = effect.commit;
536+
if (commit !== null) {
537+
effect.commit = null;
538+
commit(finishedWork);
539+
}
540+
effect = effect.nextEffect;
541+
}
536542
}

0 commit comments

Comments
 (0)