@samitouri / QOS-React / commits / fb3f7bfde9

Avoid importing Scheduler directly (#14757)

* Avoid importing Scheduler directly The reconciler should not depend directly on Scheduler. This adds it to the host config for the renderer instead. (Except for `scheduler/tracing` imports, which are used only by the profiling build. I've left those imports as-is, though I'm open to directing those through the host config, too.) * Make throwaway root id longer to appease Brian

Andrew Clark committed Feb 5, 2019 at 03:21 UTC fb3f7bfde9a326a09d827b94dddfa2628dc9346f
9 files changed +84 -61
packages/react-art/src/ReactARTHostConfig.js
+6
@@ -5,6 +5,10 @@
5 * LICENSE file in the root directory of this source tree.
6 */
7
8 +import {
9 + unstable_scheduleCallback as scheduleDeferredCallback,
10 + unstable_cancelCallback as cancelDeferredCallback,
11 +} from 'scheduler';
12 export {
13 unstable_now as now,
14 unstable_scheduleCallback as scheduleDeferredCallback,
@@ -337,6 +341,8 @@ export function getChildHostContext() {
341 export const scheduleTimeout = setTimeout;
342 export const cancelTimeout = clearTimeout;
343 export const noTimeout = -1;
344 +export const schedulePassiveEffects = scheduleDeferredCallback;
345 +export const cancelPassiveEffects = cancelDeferredCallback;
346
347 export function shouldSetTextContent(type, props) {
348 return (
packages/react-dom/src/client/ReactDOMHostConfig.js
+6
@@ -69,6 +69,10 @@ export type ChildSet = void; // Unused
69 export type TimeoutHandle = TimeoutID;
70 export type NoTimeout = -1;
71
72 +import {
73 + unstable_scheduleCallback as scheduleDeferredCallback,
74 + unstable_cancelCallback as cancelDeferredCallback,
75 +} from 'scheduler';
76 export {
77 unstable_now as now,
78 unstable_scheduleCallback as scheduleDeferredCallback,
@@ -296,6 +300,8 @@ export const scheduleTimeout =
300 export const cancelTimeout =
301 typeof clearTimeout === 'function' ? clearTimeout : (undefined: any);
302 export const noTimeout = -1;
303 +export const schedulePassiveEffects = scheduleDeferredCallback;
304 +export const cancelPassiveEffects = cancelDeferredCallback;
305
306 // -------------------
307 // Mutation
packages/react-native-renderer/src/ReactFabricHostConfig.js
+2
@@ -330,6 +330,8 @@ export const shouldYield = ReactNativeFrameSchedulingShouldYield;
330 export const scheduleTimeout = setTimeout;
331 export const cancelTimeout = clearTimeout;
332 export const noTimeout = -1;
333 +export const schedulePassiveEffects = scheduleDeferredCallback;
334 +export const cancelPassiveEffects = cancelDeferredCallback;
335
336 // -------------------
337 // Persistence
packages/react-native-renderer/src/ReactNativeHostConfig.js
+2
@@ -243,6 +243,8 @@ export const shouldYield = ReactNativeFrameSchedulingShouldYield;
243 export const scheduleTimeout = setTimeout;
244 export const cancelTimeout = clearTimeout;
245 export const noTimeout = -1;
246 +export const schedulePassiveEffects = scheduleDeferredCallback;
247 +export const cancelPassiveEffects = cancelDeferredCallback;
248
249 export function shouldDeprioritizeSubtree(type: string, props: Props): boolean {
250 return false;
packages/react-noop-renderer/src/createReactNoop.js
+26
@@ -47,6 +47,7 @@ if (__DEV__) {
47 function createReactNoop(reconciler: Function, useMutation: boolean) {
48 let scheduledCallback = null;
49 let scheduledCallbackTimeout = -1;
50 + let scheduledPassiveCallback = null;
51 let instanceCounter = 0;
52 let hostDiffCounter = 0;
53 let hostUpdateCounter = 0;
@@ -338,6 +339,21 @@ function createReactNoop(reconciler: Function, useMutation: boolean) {
339 scheduleTimeout: setTimeout,
340 cancelTimeout: clearTimeout,
341 noTimeout: -1,
342 + schedulePassiveEffects(callback) {
343 + if (scheduledCallback) {
344 + throw new Error(
345 + 'Scheduling a callback twice is excessive. Instead, keep track of ' +
346 + 'whether the callback has already been scheduled.',
347 + );
348 + }
349 + scheduledPassiveCallback = callback;
350 + },
351 + cancelPassiveEffects() {
352 + if (scheduledPassiveCallback === null) {
353 + throw new Error('No passive effects callback is scheduled.');
354 + }
355 + scheduledPassiveCallback = null;
356 + },
357
358 prepareForCommit(): void {},
359
@@ -854,6 +870,16 @@ function createReactNoop(reconciler: Function, useMutation: boolean) {
870 return yieldedValues;
871 },
872
873 + flushPassiveEffects() {
874 + // Trick to flush passive effects without exposing an internal API:
875 + // Create a throwaway root and schedule a dummy update on it.
876 + const rootID = 'bloopandthenmoreletterstoavoidaconflict';
877 + const container = {rootID: rootID, children: []};
878 + rootContainers.set(rootID, container);
879 + const root = NoopRenderer.createContainer(container, true, false);
880 + NoopRenderer.updateContainer(null, root, null, null);
881 + },
882 +
883 // Logs the current state of the tree.
884 dumpTree(rootID: string = DEFAULT_ROOT_ID) {
885 const root = roots.get(rootID);
packages/react-reconciler/src/ReactFiberScheduler.js
+6 -6
@@ -17,10 +17,6 @@ import {
17 __subscriberRef,
18 unstable_wrap as Schedule_tracing_wrap,
19 } from 'scheduler/tracing';
20 -import {
21 - unstable_scheduleCallback as Schedule_scheduleCallback,
22 - unstable_cancelCallback as Schedule_cancelCallback,
23 -} from 'scheduler';
20 import {
21 invokeGuardedCallback,
22 hasCaughtError,
@@ -83,6 +79,8 @@ import {
79 scheduleTimeout,
80 cancelTimeout,
81 noTimeout,
82 + schedulePassiveEffects,
83 + cancelPassiveEffects,
84 } from './ReactFiberHostConfig';
85 import {
86 markPendingPriorityLevel,
@@ -587,8 +585,10 @@ function markLegacyErrorBoundaryAsFailed(instance: mixed) {
585 }
586
587 function flushPassiveEffects() {
588 + if (passiveEffectCallbackHandle !== null) {
589 + cancelPassiveEffects(passiveEffectCallbackHandle);
590 + }
591 if (passiveEffectCallback !== null) {
591 - Schedule_cancelCallback(passiveEffectCallbackHandle);
592 // We call the scheduled callback instead of commitPassiveEffects directly
593 // to ensure tracing works correctly.
594 passiveEffectCallback();
@@ -795,7 +795,7 @@ function commitRoot(root: FiberRoot, finishedWork: Fiber): void {
795 // here because that code is still in flux.
796 callback = Schedule_tracing_wrap(callback);
797 }
798 - passiveEffectCallbackHandle = Schedule_scheduleCallback(callback);
798 + passiveEffectCallbackHandle = schedulePassiveEffects(callback);
799 passiveEffectCallback = callback;
800 }
801
packages/react-reconciler/src/__tests__/ReactHooksWithNoopRenderer-test.internal.js
+32 -55
@@ -25,7 +25,6 @@ let useMemo;
25 let useRef;
26 let useImperativeHandle;
27 let forwardRef;
28 -let flushPassiveEffects;
28 let memo;
29
30 // These tests use React Noop Renderer. All new tests should use React Test
@@ -35,28 +34,6 @@ describe('ReactHooksWithNoopRenderer', () => {
34 beforeEach(() => {
35 jest.resetModules();
36
38 - jest.mock('scheduler', () => {
39 - let scheduledCallbacks = new Map();
40 -
41 - flushPassiveEffects = () => {
42 - scheduledCallbacks.forEach(cb => {
43 - cb();
44 - });
45 - scheduledCallbacks = new Map();
46 - };
47 -
48 - return {
49 - unstable_scheduleCallback(callback) {
50 - const handle = {};
51 - scheduledCallbacks.set(handle, callback);
52 - return handle;
53 - },
54 - unstable_cancelCallback(handle) {
55 - scheduledCallbacks.delete(handle);
56 - },
57 - };
58 - });
59 -
37 ReactFeatureFlags = require('shared/ReactFeatureFlags');
38 ReactFeatureFlags.debugRenderPhaseSideEffectsForStrictMode = false;
39 ReactFeatureFlags.enableSchedulerTracing = true;
@@ -609,14 +586,14 @@ describe('ReactHooksWithNoopRenderer', () => {
586 ReactNoop.render(<Counter count={0} />);
587 expect(ReactNoop.flush()).toEqual(['Count: 0']);
588 expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
612 - flushPassiveEffects();
589 + ReactNoop.flushPassiveEffects();
590 expect(ReactNoop.clearYields()).toEqual(['Did commit [0]']);
591
592 ReactNoop.render(<Counter count={1} />);
593 expect(ReactNoop.flush()).toEqual(['Count: 1']);
594 expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]);
595 // Effects are deferred until after the commit
619 - flushPassiveEffects();
596 + ReactNoop.flushPassiveEffects();
597 expect(ReactNoop.clearYields()).toEqual(['Did commit [1]']);
598 });
599
@@ -648,7 +625,7 @@ describe('ReactHooksWithNoopRenderer', () => {
625 expect(ReactNoop.getChildren()).toEqual([span('Passive')]);
626
627 // (No effects are left to flush.)
651 - flushPassiveEffects();
628 + ReactNoop.flushPassiveEffects();
629 expect(ReactNoop.clearYields()).toEqual(null);
630 });
631
@@ -747,7 +724,7 @@ describe('ReactHooksWithNoopRenderer', () => {
724 ]);
725 expect(ReactNoop.getChildren()).toEqual([span(1)]);
726
750 - flushPassiveEffects();
727 + ReactNoop.flushPassiveEffects();
728 expect(ReactNoop.clearYields()).toEqual([
729 'Committed state when effect was fired: 1',
730 ]);
@@ -769,14 +746,14 @@ describe('ReactHooksWithNoopRenderer', () => {
746 ReactNoop.render(<Counter count={0} />);
747 expect(ReactNoop.flush()).toEqual(['Count: (empty)']);
748 expect(ReactNoop.getChildren()).toEqual([span('Count: (empty)')]);
772 - flushPassiveEffects();
749 + ReactNoop.flushPassiveEffects();
750 expect(ReactNoop.clearYields()).toEqual(['Schedule update [0]']);
751 expect(ReactNoop.flush()).toEqual(['Count: 0']);
752
753 ReactNoop.render(<Counter count={1} />);
754 expect(ReactNoop.flush()).toEqual(['Count: 0']);
755 expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
779 - flushPassiveEffects();
756 + ReactNoop.flushPassiveEffects();
757 expect(ReactNoop.clearYields()).toEqual(['Schedule update [1]']);
758 expect(ReactNoop.flush()).toEqual(['Count: 1']);
759 });
@@ -805,7 +782,7 @@ describe('ReactHooksWithNoopRenderer', () => {
782 expect(ReactNoop.flush()).toEqual([]);
783 expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
784
808 - flushPassiveEffects();
785 + ReactNoop.flushPassiveEffects();
786 expect(ReactNoop.flush()).toEqual(['Schedule update [1]', 'Count: 1']);
787 expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]);
788 });
@@ -908,7 +885,7 @@ describe('ReactHooksWithNoopRenderer', () => {
885 expect(ReactNoop.flush()).toEqual(['Count: (empty)']);
886 expect(ReactNoop.getChildren()).toEqual([span('Count: (empty)')]);
887 // Now fire the effects
911 - flushPassiveEffects();
888 + ReactNoop.flushPassiveEffects();
889 // There were multiple updates, but there should only be a
890 // single render
891 expect(ReactNoop.clearYields()).toEqual(['Count: 0']);
@@ -935,7 +912,7 @@ describe('ReactHooksWithNoopRenderer', () => {
912 expect(ReactNoop.getChildren()).toEqual([span('Count: (empty)')]);
913
914 expect(() => {
938 - flushPassiveEffects();
915 + ReactNoop.flushPassiveEffects();
916 }).toThrow('flushSync was called from inside a lifecycle method');
917 });
918
@@ -952,13 +929,13 @@ describe('ReactHooksWithNoopRenderer', () => {
929 ReactNoop.render(<Counter count={0} />);
930 expect(ReactNoop.flush()).toEqual(['Count: 0']);
931 expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
955 - flushPassiveEffects();
932 + ReactNoop.flushPassiveEffects();
933 expect(ReactNoop.clearYields()).toEqual(['Did create [0]']);
934
935 ReactNoop.render(<Counter count={1} />);
936 expect(ReactNoop.flush()).toEqual(['Count: 1']);
937 expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]);
961 - flushPassiveEffects();
938 + ReactNoop.flushPassiveEffects();
939 expect(ReactNoop.clearYields()).toEqual([
940 'Did destroy [0]',
941 'Did create [1]',
@@ -978,7 +955,7 @@ describe('ReactHooksWithNoopRenderer', () => {
955 ReactNoop.render(<Counter count={0} />);
956 expect(ReactNoop.flush()).toEqual(['Count: 0']);
957 expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
981 - flushPassiveEffects();
958 + ReactNoop.flushPassiveEffects();
959 expect(ReactNoop.clearYields()).toEqual(['Did create [0]']);
960
961 ReactNoop.render(null);
@@ -999,13 +976,13 @@ describe('ReactHooksWithNoopRenderer', () => {
976 ReactNoop.render(<Counter count={0} />);
977 expect(ReactNoop.flush()).toEqual(['Count: 0']);
978 expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
1002 - flushPassiveEffects();
979 + ReactNoop.flushPassiveEffects();
980 expect(ReactNoop.clearYields()).toEqual(['Did create [0]']);
981
982 ReactNoop.render(<Counter count={1} />);
983 expect(ReactNoop.flush()).toEqual(['Count: 1']);
984 expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]);
1008 - flushPassiveEffects();
985 + ReactNoop.flushPassiveEffects();
986 expect(ReactNoop.clearYields()).toEqual(null);
987
988 ReactNoop.render(null);
@@ -1027,13 +1004,13 @@ describe('ReactHooksWithNoopRenderer', () => {
1004 ReactNoop.render(<Counter count={0} />);
1005 expect(ReactNoop.flush()).toEqual(['Count: 0']);
1006 expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
1030 - flushPassiveEffects();
1007 + ReactNoop.flushPassiveEffects();
1008 expect(ReactNoop.clearYields()).toEqual(['Did create']);
1009
1010 ReactNoop.render(<Counter count={1} />);
1011 expect(ReactNoop.flush()).toEqual(['Count: 1']);
1012 expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]);
1036 - flushPassiveEffects();
1013 + ReactNoop.flushPassiveEffects();
1014 expect(ReactNoop.clearYields()).toEqual(['Did destroy', 'Did create']);
1015
1016 ReactNoop.render(null);
@@ -1057,7 +1034,7 @@ describe('ReactHooksWithNoopRenderer', () => {
1034 }
1035 ReactNoop.render(<Counter label="Count" count={0} />);
1036 expect(ReactNoop.flush()).toEqual(['Count: 0']);
1060 - flushPassiveEffects();
1037 + ReactNoop.flushPassiveEffects();
1038 expect(ReactNoop.clearYields()).toEqual(['Did create [Count: 0]']);
1039 expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
1040
@@ -1065,7 +1042,7 @@ describe('ReactHooksWithNoopRenderer', () => {
1042 // Count changed
1043 expect(ReactNoop.flush()).toEqual(['Count: 1']);
1044 expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]);
1068 - flushPassiveEffects();
1045 + ReactNoop.flushPassiveEffects();
1046 expect(ReactNoop.clearYields()).toEqual([
1047 'Did destroy [Count: 0]',
1048 'Did create [Count: 1]',
@@ -1074,7 +1051,7 @@ describe('ReactHooksWithNoopRenderer', () => {
1051 ReactNoop.render(<Counter label="Count" count={1} />);
1052 // Nothing changed, so no effect should have fired
1053 expect(ReactNoop.flush()).toEqual(['Count: 1']);
1077 - flushPassiveEffects();
1054 + ReactNoop.flushPassiveEffects();
1055 expect(ReactNoop.clearYields()).toEqual(null);
1056 expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]);
1057
@@ -1082,7 +1059,7 @@ describe('ReactHooksWithNoopRenderer', () => {
1059 // Label changed
1060 expect(ReactNoop.flush()).toEqual(['Total: 1']);
1061 expect(ReactNoop.getChildren()).toEqual([span('Total: 1')]);
1085 - flushPassiveEffects();
1062 + ReactNoop.flushPassiveEffects();
1063 expect(ReactNoop.clearYields()).toEqual([
1064 'Did destroy [Count: 1]',
1065 'Did create [Total: 1]',
@@ -1102,7 +1079,7 @@ describe('ReactHooksWithNoopRenderer', () => {
1079 ReactNoop.render(<Counter count={0} />);
1080 expect(ReactNoop.flush()).toEqual(['Count: 0']);
1081 expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
1105 - flushPassiveEffects();
1082 + ReactNoop.flushPassiveEffects();
1083 expect(ReactNoop.clearYields()).toEqual([
1084 'Did commit 1 [0]',
1085 'Did commit 2 [0]',
@@ -1111,7 +1088,7 @@ describe('ReactHooksWithNoopRenderer', () => {
1088 ReactNoop.render(<Counter count={1} />);
1089 expect(ReactNoop.flush()).toEqual(['Count: 1']);
1090 expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]);
1114 - flushPassiveEffects();
1091 + ReactNoop.flushPassiveEffects();
1092 expect(ReactNoop.clearYields()).toEqual([
1093 'Did commit 1 [1]',
1094 'Did commit 2 [1]',
@@ -1137,13 +1114,13 @@ describe('ReactHooksWithNoopRenderer', () => {
1114 ReactNoop.render(<Counter count={0} />);
1115 expect(ReactNoop.flush()).toEqual(['Count: 0']);
1116 expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
1140 - flushPassiveEffects();
1117 + ReactNoop.flushPassiveEffects();
1118 expect(ReactNoop.clearYields()).toEqual(['Mount A [0]', 'Mount B [0]']);
1119
1120 ReactNoop.render(<Counter count={1} />);
1121 expect(ReactNoop.flush()).toEqual(['Count: 1']);
1122 expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]);
1146 - flushPassiveEffects();
1123 + ReactNoop.flushPassiveEffects();
1124 expect(ReactNoop.clearYields()).toEqual([
1125 'Unmount A [0]',
1126 'Unmount B [0]',
@@ -1174,7 +1151,7 @@ describe('ReactHooksWithNoopRenderer', () => {
1151 ReactNoop.render(<Counter count={0} />);
1152 expect(ReactNoop.flush()).toEqual(['Count: 0']);
1153 expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
1177 - expect(() => flushPassiveEffects()).toThrow('Oops');
1154 + expect(() => ReactNoop.flushPassiveEffects()).toThrow('Oops');
1155 expect(ReactNoop.clearYields()).toEqual([
1156 'Mount A [0]',
1157 'Oops!',
@@ -1208,14 +1185,14 @@ describe('ReactHooksWithNoopRenderer', () => {
1185 ReactNoop.render(<Counter count={0} />);
1186 expect(ReactNoop.flush()).toEqual(['Count: 0']);
1187 expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
1211 - flushPassiveEffects();
1188 + ReactNoop.flushPassiveEffects();
1189 expect(ReactNoop.clearYields()).toEqual(['Mount A [0]', 'Mount B [0]']);
1190
1191 // This update will trigger an errror
1192 ReactNoop.render(<Counter count={1} />);
1193 expect(ReactNoop.flush()).toEqual(['Count: 1']);
1194 expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]);
1218 - expect(() => flushPassiveEffects()).toThrow('Oops');
1195 + expect(() => ReactNoop.flushPassiveEffects()).toThrow('Oops');
1196 expect(ReactNoop.clearYields()).toEqual([
1197 'Unmount A [0]',
1198 'Unmount B [0]',
@@ -1250,14 +1227,14 @@ describe('ReactHooksWithNoopRenderer', () => {
1227 ReactNoop.render(<Counter count={0} />);
1228 expect(ReactNoop.flush()).toEqual(['Count: 0']);
1229 expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
1253 - flushPassiveEffects();
1230 + ReactNoop.flushPassiveEffects();
1231 expect(ReactNoop.clearYields()).toEqual(['Mount A [0]', 'Mount B [0]']);
1232
1233 // This update will trigger an errror
1234 ReactNoop.render(<Counter count={1} />);
1235 expect(ReactNoop.flush()).toEqual(['Count: 1']);
1236 expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]);
1260 - expect(() => flushPassiveEffects()).toThrow('Oops');
1237 + expect(() => ReactNoop.flushPassiveEffects()).toThrow('Oops');
1238 expect(ReactNoop.clearYields()).toEqual([
1239 'Oops!',
1240 // B unmounts even though an error was thrown in the previous effect
@@ -1351,7 +1328,7 @@ describe('ReactHooksWithNoopRenderer', () => {
1328 ]);
1329 expect(committedText).toEqual('1');
1330
1354 - flushPassiveEffects();
1331 + ReactNoop.flushPassiveEffects();
1332 expect(ReactNoop.clearYields()).toEqual([
1333 'Unmount normal [current: 1]',
1334 'Mount normal [current: 1]',
@@ -1705,7 +1682,7 @@ describe('ReactHooksWithNoopRenderer', () => {
1682
1683 ReactNoop.render(<App showMore={false} />);
1684 expect(ReactNoop.flush()).toEqual([]);
1708 - flushPassiveEffects();
1685 + ReactNoop.flushPassiveEffects();
1686 expect(ReactNoop.clearYields()).toEqual(['Mount A']);
1687
1688 ReactNoop.render(<App showMore={true} />);
@@ -1714,7 +1691,7 @@ describe('ReactHooksWithNoopRenderer', () => {
1691 }).toThrow('Rendered more hooks than during the previous render');
1692
1693 // Uncomment if/when we support this again
1717 - // flushPassiveEffects();
1694 + // ReactNoop.flushPassiveEffects();
1695 // expect(ReactNoop.clearYields()).toEqual(['Mount B']);
1696
1697 // ReactNoop.render(<App showMore={false} />);
packages/react-reconciler/src/forks/ReactFiberHostConfig.custom.js
+2
@@ -56,6 +56,8 @@ export const shouldYield = $$$hostConfig.shouldYield;
56 export const scheduleTimeout = $$$hostConfig.setTimeout;
57 export const cancelTimeout = $$$hostConfig.clearTimeout;
58 export const noTimeout = $$$hostConfig.noTimeout;
59 +export const schedulePassiveEffects = $$$hostConfig.schedulePassiveEffects;
60 +export const cancelPassiveEffects = $$$hostConfig.cancelPassiveEffects;
61 export const now = $$$hostConfig.now;
62 export const isPrimaryRenderer = $$$hostConfig.isPrimaryRenderer;
63 export const supportsMutation = $$$hostConfig.supportsMutation;
packages/react-test-renderer/src/ReactTestHostConfig.js
+2
@@ -210,6 +210,8 @@ export const shouldYield = TestRendererSchedulingShouldYield;
210 export const scheduleTimeout = setTimeout;
211 export const cancelTimeout = clearTimeout;
212 export const noTimeout = -1;
213 +export const schedulePassiveEffects = scheduleDeferredCallback;
214 +export const cancelPassiveEffects = cancelDeferredCallback;
215
216 // -------------------
217 // Mutation