@samitouri / QOS-React / commits / 75a1c2e72a

The Lost Effect, chapter 3

wow, writing code is hard

Sophie Alpert committed Oct 12, 2018 at 18:04 UTC 75a1c2e72a8ebff2ec5e9b89e3c0e04f576731b7
6 files changed +43 -39
packages/react-reconciler/src/ReactFiberClassComponent.js
+4 -4
@@ -51,7 +51,7 @@ import {
51 requestCurrentTime,
52 computeExpirationForFiber,
53 scheduleWork,
54 - flushPassiveEffectsBeforeSchedulingUpdateOnFiber,
54 + flushPassiveEffects,
55 } from './ReactFiberScheduler';
56
57 const ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner;
@@ -200,7 +200,7 @@ const classComponentUpdater = {
200 update.callback = callback;
201 }
202
203 - flushPassiveEffectsBeforeSchedulingUpdateOnFiber(fiber);
203 + flushPassiveEffects();
204 enqueueUpdate(fiber, update);
205 scheduleWork(fiber, expirationTime);
206 },
@@ -220,7 +220,7 @@ const classComponentUpdater = {
220 update.callback = callback;
221 }
222
223 - flushPassiveEffectsBeforeSchedulingUpdateOnFiber(fiber);
223 + flushPassiveEffects();
224 enqueueUpdate(fiber, update);
225 scheduleWork(fiber, expirationTime);
226 },
@@ -239,7 +239,7 @@ const classComponentUpdater = {
239 update.callback = callback;
240 }
241
242 - flushPassiveEffectsBeforeSchedulingUpdateOnFiber(fiber);
242 + flushPassiveEffects();
243 enqueueUpdate(fiber, update);
244 scheduleWork(fiber, expirationTime);
245 },
packages/react-reconciler/src/ReactFiberCommitWork.js
+2 -2
@@ -85,7 +85,7 @@ import {
85 } from './ReactFiberHostConfig';
86 import {
87 captureCommitPhaseError,
88 - flushPassiveEffectsBeforeSchedulingUpdateOnFiber,
88 + flushPassiveEffects,
89 requestCurrentTime,
90 scheduleWork,
91 } from './ReactFiberScheduler';
@@ -457,7 +457,7 @@ function commitLifeCycles(
457 timedOutAt: NoWork,
458 };
459 finishedWork.memoizedState = newState;
460 - flushPassiveEffectsBeforeSchedulingUpdateOnFiber(finishedWork);
460 + flushPassiveEffects();
461 scheduleWork(finishedWork, Sync);
462 return;
463 }
packages/react-reconciler/src/ReactFiberHooks.js
+2 -2
@@ -32,7 +32,7 @@ import {
32 import {
33 scheduleWork,
34 computeExpirationForFiber,
35 - flushPassiveEffectsBeforeSchedulingUpdateOnFiber,
35 + flushPassiveEffects,
36 requestCurrentTime,
37 } from './ReactFiberScheduler';
38
@@ -725,7 +725,7 @@ function dispatchAction<S, A>(
725 callback: callback !== undefined ? callback : null,
726 next: null,
727 };
728 - flushPassiveEffectsBeforeSchedulingUpdateOnFiber(fiber);
728 + flushPassiveEffects();
729 // Append the update to the end of the list.
730 const last = queue.last;
731 if (last === null) {
packages/react-reconciler/src/ReactFiberReconciler.js
+2 -2
@@ -52,7 +52,7 @@ import {
52 syncUpdates,
53 interactiveUpdates,
54 flushInteractiveUpdates,
55 - flushPassiveEffectsBeforeSchedulingUpdateOnFiber,
55 + flushPassiveEffects,
56 } from './ReactFiberScheduler';
57 import {createUpdate, enqueueUpdate} from './ReactUpdateQueue';
58 import ReactFiberInstrumentation from './ReactFiberInstrumentation';
@@ -147,7 +147,7 @@ function scheduleRootUpdate(
147 update.callback = callback;
148 }
149
150 - flushPassiveEffectsBeforeSchedulingUpdateOnFiber(current);
150 + flushPassiveEffects();
151 enqueueUpdate(current, update);
152 scheduleWork(current, expirationTime);
153
packages/react-reconciler/src/ReactFiberScheduler.js
+4 -29
@@ -578,33 +578,8 @@ function markLegacyErrorBoundaryAsFailed(instance: mixed) {
578 }
579 }
580
581 -function flushPassiveEffectsBeforeSchedulingUpdateOnFiber(fiber: Fiber) {
582 - if (rootWithPendingPassiveEffects !== null) {
583 - // TODO: This is an unfortunate extra loop. We end up traversing to the root
584 - // again in scheduleWorkToRoot. But we have to do this one first because it
585 - // needs to happen before adding an update to the queue, and
586 - // scheduleWorkToRoot may perform a synchronous re-render. Maybe we can
587 - // solve this with batchedUpdates, or with the equivalent in the Scheduler
588 - // package.
589 - let node = fiber;
590 - do {
591 - switch (node.tag) {
592 - case HostRoot: {
593 - const root: FiberRoot = node.stateNode;
594 - flushPassiveEffects(root);
595 - return;
596 - }
597 - }
598 - node = node.return;
599 - } while (node !== null);
600 - }
601 -}
602 -
603 -function flushPassiveEffects(root: FiberRoot) {
604 - if (
605 - passiveEffectCallback !== null &&
606 - root === rootWithPendingPassiveEffects
607 - ) {
581 +function flushPassiveEffects() {
582 + if (passiveEffectCallback !== null) {
583 Schedule_cancelCallback(passiveEffectCallbackHandle);
584 // We call the scheduled callback instead of commitPassiveEffects directly
585 // to ensure tracing works correctly.
@@ -1248,7 +1223,7 @@ function renderRoot(
1223 'by a bug in React. Please file an issue.',
1224 );
1225
1251 - flushPassiveEffects(root);
1226 + flushPassiveEffects();
1227
1228 isWorking = true;
1229 ReactCurrentOwner.currentDispatcher = Dispatcher;
@@ -2613,5 +2588,5 @@ export {
2588 interactiveUpdates,
2589 flushInteractiveUpdates,
2590 computeUniqueAsyncExpiration,
2616 - flushPassiveEffectsBeforeSchedulingUpdateOnFiber,
2591 + flushPassiveEffects,
2592 };
packages/react-reconciler/src/__tests__/ReactHooks-test.internal.js
+29
@@ -717,6 +717,35 @@ describe('ReactHooks', () => {
717 ]);
718 });
719
720 + it('flushes passive effects even if siblings schedule a new root', () => {
721 + function PassiveEffect(props) {
722 + useEffect(() => {
723 + ReactNoop.yield('Passive effect');
724 + }, []);
725 + return <Text text="Passive" />;
726 + }
727 + function LayoutEffect(props) {
728 + useLayoutEffect(() => {
729 + ReactNoop.yield('Layout effect');
730 + // Scheduling work shouldn't interfere with the queued passive effect
731 + ReactNoop.renderToRootWithID(<Text text="New Root" />, 'root2');
732 + });
733 + return <Text text="Layout" />;
734 + }
735 + ReactNoop.render([<PassiveEffect key="p" />, <LayoutEffect key="l" />]);
736 + expect(ReactNoop.flush()).toEqual([
737 + 'Passive',
738 + 'Layout',
739 + 'Layout effect',
740 + 'Passive effect',
741 + 'New Root',
742 + ]);
743 + expect(ReactNoop.getChildren()).toEqual([
744 + span('Passive'),
745 + span('Layout'),
746 + ]);
747 + });
748 +
749 it(
750 'flushes effects serially by flushing old effects before flushing ' +
751 "new ones, if they haven't already fired",