Skip to content

Commit 995a437

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 34b65b1 commit 995a437

File tree

1 file changed

+52
-13
lines changed

1 file changed

+52
-13
lines changed

packages/react-reconciler/src/ReactUpdateQueue.js

Lines changed: 52 additions & 13 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;
@@ -428,12 +436,22 @@ export function processUpdateQueue<State>(
428436
} else {
429437
// This update does have sufficient priority. Process it and compute
430438
// a new result.
431-
resultState = processSingleUpdate(
432-
workInProgress,
433-
queue,
434-
update,
435-
resultState,
436-
);
439+
const commit = update.commit;
440+
const process = update.process;
441+
if (process !== null) {
442+
resultState = process(workInProgress, resultState, queue);
443+
}
444+
if (commit !== null) {
445+
workInProgress.effectTag |= Callback;
446+
// Set this to null, in case it was mutated during an aborted render.
447+
update.nextEffect = null;
448+
if (queue.lastEffect === null) {
449+
queue.firstEffect = queue.lastEffect = update;
450+
} else {
451+
queue.lastEffect.nextEffect = update;
452+
queue.lastEffect = update;
453+
}
454+
}
437455
}
438456
// Continue to the next update.
439457
update = update.next;
@@ -467,12 +485,22 @@ export function processUpdateQueue<State>(
467485
} else {
468486
// This update does have sufficient priority. Process it and compute
469487
// a new result.
470-
resultState = processSingleUpdate(
471-
workInProgress,
472-
queue,
473-
update,
474-
resultState,
475-
);
488+
const commit = update.commit;
489+
const process = update.process;
490+
if (process !== null) {
491+
resultState = process(workInProgress, resultState, queue);
492+
}
493+
if (commit !== null) {
494+
workInProgress.effectTag |= Callback;
495+
// Set this to null, in case it was mutated during an aborted render.
496+
update.nextEffect = null;
497+
if (queue.lastCapturedEffect === null) {
498+
queue.firstCapturedEffect = queue.lastCapturedEffect = update;
499+
} else {
500+
queue.lastCapturedEffect.nextEffect = update;
501+
queue.lastCapturedEffect = update;
502+
}
503+
}
476504
}
477505
update = update.next;
478506
}
@@ -533,4 +561,15 @@ export function commitUpdateQueue<State>(
533561
}
534562
effect = effect.nextEffect;
535563
}
564+
565+
effect = finishedQueue.firstCapturedEffect;
566+
finishedQueue.firstCapturedEffect = finishedQueue.lastCapturedEffect = null;
567+
while (effect !== null) {
568+
const commit = effect.commit;
569+
if (commit !== null) {
570+
effect.commit = null;
571+
commit(finishedWork);
572+
}
573+
effect = effect.nextEffect;
574+
}
536575
}

0 commit comments

Comments
 (0)