7
* @flow
8
*/
9
10
-import type {Fiber} from './ReactFiber';
11
-import type {FiberRoot} from './ReactFiberRoot';
12
-import type {RootTag} from 'shared/ReactRootTags';
13
-import type {
14
- Instance,
15
- TextInstance,
16
- Container,
17
- PublicInstance,
18
-} from './ReactFiberHostConfig';
19
-import {FundamentalComponent} from 'shared/ReactWorkTags';
20
-import type {ReactNodeList} from 'shared/ReactTypes';
21
-import type {ExpirationTime} from './ReactFiberExpirationTime';
22
-import type {
23
- SuspenseHydrationCallbacks,
24
- SuspenseState,
25
-} from './ReactFiberSuspenseComponent';
10
+import {enableNewReconciler} from 'shared/ReactFeatureFlags';
11
27
-import {
28
- findCurrentHostFiber,
29
- findCurrentHostFiberWithNoPortals,
30
-} from 'react-reconciler/src/ReactFiberTreeReflection';
31
-import {get as getInstance} from 'shared/ReactInstanceMap';
32
-import {
33
- HostComponent,
34
- ClassComponent,
35
- HostRoot,
36
- SuspenseComponent,
37
-} from 'shared/ReactWorkTags';
38
-import getComponentName from 'shared/getComponentName';
39
-import invariant from 'shared/invariant';
40
-import ReactSharedInternals from 'shared/ReactSharedInternals';
12
+// The entry file imports either the old or new version of the reconciler.
13
+// During build and testing, this indirection is always shimmed with the actual
14
+// modules, otherwise both reconcilers would be initialized. So this is really
15
+// only here for Flow purposes.
16
42
-import {getPublicInstance} from './ReactFiberHostConfig';
43
-import {
44
- findCurrentUnmaskedContext,
45
- processChildContext,
46
- emptyContextObject,
47
- isContextProvider as isLegacyContextProvider,
48
-} from './ReactFiberContext';
49
-import {createFiberRoot} from './ReactFiberRoot';
50
-import {injectInternals, onScheduleRoot} from './ReactFiberDevToolsHook';
51
-import {
52
- requestCurrentTimeForUpdate,
53
- computeExpirationForFiber,
54
- scheduleUpdateOnFiber,
55
- flushRoot,
56
- batchedEventUpdates,
57
- batchedUpdates,
58
- unbatchedUpdates,
59
- flushSync,
60
- flushControlled,
61
- deferredUpdates,
62
- syncUpdates,
63
- discreteUpdates,
64
- flushDiscreteUpdates,
65
- flushPassiveEffects,
66
- warnIfNotScopedWithMatchingAct,
67
- warnIfUnmockedScheduler,
68
- IsThisRendererActing,
69
-} from './ReactFiberWorkLoop';
70
-import {createUpdate, enqueueUpdate} from './ReactUpdateQueue';
17
import {
72
- getStackByFiberInDevAndProd,
73
- isRendering as ReactCurrentFiberIsRendering,
74
- current as ReactCurrentFiberCurrent,
75
-} from './ReactCurrentFiber';
76
-import {StrictMode} from './ReactTypeOfMode';
18
+ createContainer as createContainer_old,
19
+ updateContainer as updateContainer_old,
20
+ batchedEventUpdates as batchedEventUpdates_old,
21
+ batchedUpdates as batchedUpdates_old,
22
+ unbatchedUpdates as unbatchedUpdates_old,
23
+ deferredUpdates as deferredUpdates_old,
24
+ syncUpdates as syncUpdates_old,
25
+ discreteUpdates as discreteUpdates_old,
26
+ flushDiscreteUpdates as flushDiscreteUpdates_old,
27
+ flushControlled as flushControlled_old,
28
+ flushSync as flushSync_old,
29
+ flushPassiveEffects as flushPassiveEffects_old,
30
+ IsThisRendererActing as IsThisRendererActing_old,
31
+ getPublicRootInstance as getPublicRootInstance_old,
32
+ attemptSynchronousHydration as attemptSynchronousHydration_old,
33
+ attemptUserBlockingHydration as attemptUserBlockingHydration_old,
34
+ attemptContinuousHydration as attemptContinuousHydration_old,
35
+ attemptHydrationAtCurrentPriority as attemptHydrationAtCurrentPriority_old,
36
+ findHostInstance as findHostInstance_old,
37
+ findHostInstanceWithWarning as findHostInstanceWithWarning_old,
38
+ findHostInstanceWithNoPortals as findHostInstanceWithNoPortals_old,
39
+ shouldSuspend as shouldSuspend_old,
40
+ injectIntoDevTools as injectIntoDevTools_old,
41
+ act as act_old,
42
+} from './ReactFiberReconciler.old';
43
+
44
+// TODO: Update these to point to the fork.
45
import {
78
- Sync,
79
- ContinuousHydration,
80
- computeInteractiveExpiration,
81
-} from './ReactFiberExpirationTime';
82
-import {requestCurrentSuspenseConfig} from './ReactFiberSuspenseConfig';
83
-import {
84
- scheduleRefresh,
85
- scheduleRoot,
86
- setRefreshHandler,
87
- findHostInstancesForRefresh,
88
-} from './ReactFiberHotReloading';
89
-
90
-// used by isTestEnvironment builds
91
-import enqueueTask from 'shared/enqueueTask';
92
-import * as Scheduler from 'scheduler';
93
-// end isTestEnvironment imports
94
-
95
-type OpaqueRoot = FiberRoot;
96
-
97
-// 0 is PROD, 1 is DEV.
98
-// Might add PROFILE later.
99
-type BundleType = 0 | 1;
100
-
101
-type DevToolsConfig = {|
102
- bundleType: BundleType,
103
- version: string,
104
- rendererPackageName: string,
105
- // Note: this actually *does* depend on Fiber internal fields.
106
- // Used by "inspect clicked DOM element" in React DevTools.
107
- findFiberByHostInstance?: (instance: Instance | TextInstance) => Fiber | null,
108
- // Used by RN in-app inspector.
109
- // This API is unfortunately RN-specific.
110
- // TODO: Change it to accept Fiber instead and type it properly.
111
- getInspectorDataForViewTag?: (tag: number) => Object,
112
-|};
113
-
114
-let didWarnAboutNestedUpdates;
115
-let didWarnAboutFindNodeInStrictMode;
116
-
117
-if (__DEV__) {
118
- didWarnAboutNestedUpdates = false;
119
- didWarnAboutFindNodeInStrictMode = {};
120
-}
121
-
122
-function getContextForSubtree(
123
- parentComponent: ?React$Component<any, any>,
124
-): Object {
125
- if (!parentComponent) {
126
- return emptyContextObject;
127
- }
128
-
129
- const fiber = getInstance(parentComponent);
130
- const parentContext = findCurrentUnmaskedContext(fiber);
131
-
132
- if (fiber.tag === ClassComponent) {
133
- const Component = fiber.type;
134
- if (isLegacyContextProvider(Component)) {
135
- return processChildContext(fiber, Component, parentContext);
136
- }
137
- }
138
-
139
- return parentContext;
140
-}
141
-
142
-function findHostInstance(component: Object): PublicInstance | null {
143
- const fiber = getInstance(component);
144
- if (fiber === undefined) {
145
- if (typeof component.render === 'function') {
146
- invariant(false, 'Unable to find node on an unmounted component.');
147
- } else {
148
- invariant(
149
- false,
150
- 'Argument appears to not be a ReactComponent. Keys: %s',
151
- Object.keys(component),
152
- );
153
- }
154
- }
155
- const hostFiber = findCurrentHostFiber(fiber);
156
- if (hostFiber === null) {
157
- return null;
158
- }
159
- return hostFiber.stateNode;
160
-}
161
-
162
-function findHostInstanceWithWarning(
163
- component: Object,
164
- methodName: string,
165
-): PublicInstance | null {
166
- if (__DEV__) {
167
- const fiber = getInstance(component);
168
- if (fiber === undefined) {
169
- if (typeof component.render === 'function') {
170
- invariant(false, 'Unable to find node on an unmounted component.');
171
- } else {
172
- invariant(
173
- false,
174
- 'Argument appears to not be a ReactComponent. Keys: %s',
175
- Object.keys(component),
176
- );
177
- }
178
- }
179
- const hostFiber = findCurrentHostFiber(fiber);
180
- if (hostFiber === null) {
181
- return null;
182
- }
183
- if (hostFiber.mode & StrictMode) {
184
- const componentName = getComponentName(fiber.type) || 'Component';
185
- if (!didWarnAboutFindNodeInStrictMode[componentName]) {
186
- didWarnAboutFindNodeInStrictMode[componentName] = true;
187
- if (fiber.mode & StrictMode) {
188
- console.error(
189
- '%s is deprecated in StrictMode. ' +
190
- '%s was passed an instance of %s which is inside StrictMode. ' +
191
- 'Instead, add a ref directly to the element you want to reference. ' +
192
- 'Learn more about using refs safely here: ' +
193
- 'https://fb.me/react-strict-mode-find-node%s',
194
- methodName,
195
- methodName,
196
- componentName,
197
- getStackByFiberInDevAndProd(hostFiber),
198
- );
199
- } else {
200
- console.error(
201
- '%s is deprecated in StrictMode. ' +
202
- '%s was passed an instance of %s which renders StrictMode children. ' +
203
- 'Instead, add a ref directly to the element you want to reference. ' +
204
- 'Learn more about using refs safely here: ' +
205
- 'https://fb.me/react-strict-mode-find-node%s',
206
- methodName,
207
- methodName,
208
- componentName,
209
- getStackByFiberInDevAndProd(hostFiber),
210
- );
211
- }
212
- }
213
- }
214
- return hostFiber.stateNode;
215
- }
216
- return findHostInstance(component);
217
-}
218
-
219
-export function createContainer(
220
- containerInfo: Container,
221
- tag: RootTag,
222
- hydrate: boolean,
223
- hydrationCallbacks: null | SuspenseHydrationCallbacks,
224
-): OpaqueRoot {
225
- return createFiberRoot(containerInfo, tag, hydrate, hydrationCallbacks);
226
-}
227
-
228
-export function updateContainer(
229
- element: ReactNodeList,
230
- container: OpaqueRoot,
231
- parentComponent: ?React$Component<any, any>,
232
- callback: ?Function,
233
-): ExpirationTime {
234
- if (__DEV__) {
235
- onScheduleRoot(container, element);
236
- }
237
- const current = container.current;
238
- const currentTime = requestCurrentTimeForUpdate();
239
- if (__DEV__) {
240
- // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests
241
- if ('undefined' !== typeof jest) {
242
- warnIfUnmockedScheduler(current);
243
- warnIfNotScopedWithMatchingAct(current);
244
- }
245
- }
246
- const suspenseConfig = requestCurrentSuspenseConfig();
247
- const expirationTime = computeExpirationForFiber(
248
- currentTime,
249
- current,
250
- suspenseConfig,
251
- );
252
-
253
- const context = getContextForSubtree(parentComponent);
254
- if (container.context === null) {
255
- container.context = context;
256
- } else {
257
- container.pendingContext = context;
258
- }
259
-
260
- if (__DEV__) {
261
- if (
262
- ReactCurrentFiberIsRendering &&
263
- ReactCurrentFiberCurrent !== null &&
264
- !didWarnAboutNestedUpdates
265
- ) {
266
- didWarnAboutNestedUpdates = true;
267
- console.error(
268
- 'Render methods should be a pure function of props and state; ' +
269
- 'triggering nested component updates from render is not allowed. ' +
270
- 'If necessary, trigger nested updates in componentDidUpdate.\n\n' +
271
- 'Check the render method of %s.',
272
- getComponentName(ReactCurrentFiberCurrent.type) || 'Unknown',
273
- );
274
- }
275
- }
276
-
277
- const update = createUpdate(expirationTime, suspenseConfig);
278
- // Caution: React DevTools currently depends on this property
279
- // being called "element".
280
- update.payload = {element};
281
-
282
- callback = callback === undefined ? null : callback;
283
- if (callback !== null) {
284
- if (__DEV__) {
285
- if (typeof callback !== 'function') {
286
- console.error(
287
- 'render(...): Expected the last optional `callback` argument to be a ' +
288
- 'function. Instead received: %s.',
289
- callback,
290
- );
291
- }
292
- }
293
- update.callback = callback;
294
- }
295
-
296
- enqueueUpdate(current, update);
297
- scheduleUpdateOnFiber(current, expirationTime);
298
-
299
- return expirationTime;
300
-}
301
-
302
-export {
303
- batchedEventUpdates,
304
- batchedUpdates,
305
- unbatchedUpdates,
306
- deferredUpdates,
307
- syncUpdates,
308
- discreteUpdates,
309
- flushDiscreteUpdates,
310
- flushControlled,
311
- flushSync,
312
- flushPassiveEffects,
313
- IsThisRendererActing,
314
-};
315
-
316
-export function getPublicRootInstance(
317
- container: OpaqueRoot,
318
-): React$Component<any, any> | PublicInstance | null {
319
- const containerFiber = container.current;
320
- if (!containerFiber.child) {
321
- return null;
322
- }
323
- switch (containerFiber.child.tag) {
324
- case HostComponent:
325
- return getPublicInstance(containerFiber.child.stateNode);
326
- default:
327
- return containerFiber.child.stateNode;
328
- }
329
-}
330
-
331
-export function attemptSynchronousHydration(fiber: Fiber): void {
332
- switch (fiber.tag) {
333
- case HostRoot:
334
- let root: FiberRoot = fiber.stateNode;
335
- if (root.hydrate) {
336
- // Flush the first scheduled "update".
337
- flushRoot(root, root.firstPendingTime);
338
- }
339
- break;
340
- case SuspenseComponent:
341
- flushSync(() => scheduleUpdateOnFiber(fiber, Sync));
342
- // If we're still blocked after this, we need to increase
343
- // the priority of any promises resolving within this
344
- // boundary so that they next attempt also has higher pri.
345
- let retryExpTime = computeInteractiveExpiration(
346
- requestCurrentTimeForUpdate(),
347
- );
348
- markRetryTimeIfNotHydrated(fiber, retryExpTime);
349
- break;
350
- }
351
-}
352
-
353
-function markRetryTimeImpl(fiber: Fiber, retryTime: ExpirationTime) {
354
- let suspenseState: null | SuspenseState = fiber.memoizedState;
355
- if (suspenseState !== null && suspenseState.dehydrated !== null) {
356
- if (suspenseState.retryTime < retryTime) {
357
- suspenseState.retryTime = retryTime;
358
- }
359
- }
360
-}
361
-
362
-// Increases the priority of thennables when they resolve within this boundary.
363
-function markRetryTimeIfNotHydrated(fiber: Fiber, retryTime: ExpirationTime) {
364
- markRetryTimeImpl(fiber, retryTime);
365
- let alternate = fiber.alternate;
366
- if (alternate) {
367
- markRetryTimeImpl(alternate, retryTime);
368
- }
369
-}
370
-
371
-export function attemptUserBlockingHydration(fiber: Fiber): void {
372
- if (fiber.tag !== SuspenseComponent) {
373
- // We ignore HostRoots here because we can't increase
374
- // their priority and they should not suspend on I/O,
375
- // since you have to wrap anything that might suspend in
376
- // Suspense.
377
- return;
378
- }
379
- let expTime = computeInteractiveExpiration(requestCurrentTimeForUpdate());
380
- scheduleUpdateOnFiber(fiber, expTime);
381
- markRetryTimeIfNotHydrated(fiber, expTime);
382
-}
383
-
384
-export function attemptContinuousHydration(fiber: Fiber): void {
385
- if (fiber.tag !== SuspenseComponent) {
386
- // We ignore HostRoots here because we can't increase
387
- // their priority and they should not suspend on I/O,
388
- // since you have to wrap anything that might suspend in
389
- // Suspense.
390
- return;
391
- }
392
- scheduleUpdateOnFiber(fiber, ContinuousHydration);
393
- markRetryTimeIfNotHydrated(fiber, ContinuousHydration);
394
-}
395
-
396
-export function attemptHydrationAtCurrentPriority(fiber: Fiber): void {
397
- if (fiber.tag !== SuspenseComponent) {
398
- // We ignore HostRoots here because we can't increase
399
- // their priority other than synchronously flush it.
400
- return;
401
- }
402
- const currentTime = requestCurrentTimeForUpdate();
403
- const expTime = computeExpirationForFiber(currentTime, fiber, null);
404
- scheduleUpdateOnFiber(fiber, expTime);
405
- markRetryTimeIfNotHydrated(fiber, expTime);
406
-}
407
-
408
-export {findHostInstance};
409
-
410
-export {findHostInstanceWithWarning};
411
-
412
-export function findHostInstanceWithNoPortals(
413
- fiber: Fiber,
414
-): PublicInstance | null {
415
- const hostFiber = findCurrentHostFiberWithNoPortals(fiber);
416
- if (hostFiber === null) {
417
- return null;
418
- }
419
- if (hostFiber.tag === FundamentalComponent) {
420
- return hostFiber.stateNode.instance;
421
- }
422
- return hostFiber.stateNode;
423
-}
424
-
425
-let shouldSuspendImpl = fiber => false;
426
-
427
-export function shouldSuspend(fiber: Fiber): boolean {
428
- return shouldSuspendImpl(fiber);
429
-}
430
-
431
-let overrideHookState = null;
432
-let overrideProps = null;
433
-let scheduleUpdate = null;
434
-let setSuspenseHandler = null;
435
-
436
-if (__DEV__) {
437
- const copyWithSetImpl = (
438
- obj: Object | Array<any>,
439
- path: Array<string | number>,
440
- idx: number,
441
- value: any,
442
- ) => {
443
- if (idx >= path.length) {
444
- return value;
445
- }
446
- const key = path[idx];
447
- const updated = Array.isArray(obj) ? obj.slice() : {...obj};
448
- // $FlowFixMe number or string is fine here
449
- updated[key] = copyWithSetImpl(obj[key], path, idx + 1, value);
450
- return updated;
451
- };
452
-
453
- const copyWithSet = (
454
- obj: Object | Array<any>,
455
- path: Array<string | number>,
456
- value: any,
457
- ): Object | Array<any> => {
458
- return copyWithSetImpl(obj, path, 0, value);
459
- };
460
-
461
- // Support DevTools editable values for useState and useReducer.
462
- overrideHookState = (
463
- fiber: Fiber,
464
- id: number,
465
- path: Array<string | number>,
466
- value: any,
467
- ) => {
468
- // For now, the "id" of stateful hooks is just the stateful hook index.
469
- // This may change in the future with e.g. nested hooks.
470
- let currentHook = fiber.memoizedState;
471
- while (currentHook !== null && id > 0) {
472
- currentHook = currentHook.next;
473
- id--;
474
- }
475
- if (currentHook !== null) {
476
- const newState = copyWithSet(currentHook.memoizedState, path, value);
477
- currentHook.memoizedState = newState;
478
- currentHook.baseState = newState;
479
-
480
- // We aren't actually adding an update to the queue,
481
- // because there is no update we can add for useReducer hooks that won't trigger an error.
482
- // (There's no appropriate action type for DevTools overrides.)
483
- // As a result though, React will see the scheduled update as a noop and bailout.
484
- // Shallow cloning props works as a workaround for now to bypass the bailout check.
485
- fiber.memoizedProps = {...fiber.memoizedProps};
486
-
487
- scheduleUpdateOnFiber(fiber, Sync);
488
- }
489
- };
490
-
491
- // Support DevTools props for function components, forwardRef, memo, host components, etc.
492
- overrideProps = (fiber: Fiber, path: Array<string | number>, value: any) => {
493
- fiber.pendingProps = copyWithSet(fiber.memoizedProps, path, value);
494
- if (fiber.alternate) {
495
- fiber.alternate.pendingProps = fiber.pendingProps;
496
- }
497
- scheduleUpdateOnFiber(fiber, Sync);
498
- };
499
-
500
- scheduleUpdate = (fiber: Fiber) => {
501
- scheduleUpdateOnFiber(fiber, Sync);
502
- };
503
-
504
- setSuspenseHandler = (newShouldSuspendImpl: Fiber => boolean) => {
505
- shouldSuspendImpl = newShouldSuspendImpl;
506
- };
507
-}
508
-
509
-export function injectIntoDevTools(devToolsConfig: DevToolsConfig): boolean {
510
- const {findFiberByHostInstance} = devToolsConfig;
511
- const {ReactCurrentDispatcher} = ReactSharedInternals;
512
-
513
- return injectInternals({
514
- bundleType: devToolsConfig.bundleType,
515
- version: devToolsConfig.version,
516
- rendererPackageName: devToolsConfig.rendererPackageName,
517
- getInspectorDataForViewTag: devToolsConfig.getInspectorDataForViewTag,
518
- overrideHookState,
519
- overrideProps,
520
- setSuspenseHandler,
521
- scheduleUpdate,
522
- currentDispatcherRef: ReactCurrentDispatcher,
523
- findHostInstanceByFiber(fiber: Fiber): Instance | TextInstance | null {
524
- const hostFiber = findCurrentHostFiber(fiber);
525
- if (hostFiber === null) {
526
- return null;
527
- }
528
- return hostFiber.stateNode;
529
- },
530
- findFiberByHostInstance(instance: Instance | TextInstance): Fiber | null {
531
- if (!findFiberByHostInstance) {
532
- // Might not be implemented by the renderer.
533
- return null;
534
- }
535
- return findFiberByHostInstance(instance);
536
- },
537
- // React Refresh
538
- findHostInstancesForRefresh: __DEV__ ? findHostInstancesForRefresh : null,
539
- scheduleRefresh: __DEV__ ? scheduleRefresh : null,
540
- scheduleRoot: __DEV__ ? scheduleRoot : null,
541
- setRefreshHandler: __DEV__ ? setRefreshHandler : null,
542
- // Enables DevTools to append owner stacks to error messages in DEV mode.
543
- getCurrentFiber: __DEV__ ? () => ReactCurrentFiberCurrent : null,
544
- });
545
-}
546
-
547
-const {IsSomeRendererActing} = ReactSharedInternals;
548
-const isSchedulerMocked =
549
- typeof Scheduler.unstable_flushAllWithoutAsserting === 'function';
550
-const flushWork =
551
- Scheduler.unstable_flushAllWithoutAsserting ||
552
- function() {
553
- let didFlushWork = false;
554
- while (flushPassiveEffects()) {
555
- didFlushWork = true;
556
- }
557
-
558
- return didFlushWork;
559
- };
560
-
561
-function flushWorkAndMicroTasks(onDone: (err: ?Error) => void) {
562
- try {
563
- flushWork();
564
- enqueueTask(() => {
565
- if (flushWork()) {
566
- flushWorkAndMicroTasks(onDone);
567
- } else {
568
- onDone();
569
- }
570
- });
571
- } catch (err) {
572
- onDone(err);
573
- }
574
-}
575
-
576
-// we track the 'depth' of the act() calls with this counter,
577
-// so we can tell if any async act() calls try to run in parallel.
578
-
579
-let actingUpdatesScopeDepth = 0;
580
-let didWarnAboutUsingActInProd = false;
581
-
582
-// eslint-disable-next-line no-inner-declarations
583
-export function act(callback: () => Thenable) {
584
- if (!__DEV__) {
585
- if (didWarnAboutUsingActInProd === false) {
586
- didWarnAboutUsingActInProd = true;
587
- // eslint-disable-next-line react-internal/no-production-logging
588
- console.error(
589
- 'act(...) is not supported in production builds of React, and might not behave as expected.',
590
- );
591
- }
592
- }
593
-
594
- let previousActingUpdatesScopeDepth = actingUpdatesScopeDepth;
595
- let previousIsSomeRendererActing;
596
- let previousIsThisRendererActing;
597
- actingUpdatesScopeDepth++;
598
-
599
- previousIsSomeRendererActing = IsSomeRendererActing.current;
600
- previousIsThisRendererActing = IsThisRendererActing.current;
601
- IsSomeRendererActing.current = true;
602
- IsThisRendererActing.current = true;
603
-
604
- function onDone() {
605
- actingUpdatesScopeDepth--;
606
- IsSomeRendererActing.current = previousIsSomeRendererActing;
607
- IsThisRendererActing.current = previousIsThisRendererActing;
608
- if (__DEV__) {
609
- if (actingUpdatesScopeDepth > previousActingUpdatesScopeDepth) {
610
- // if it's _less than_ previousActingUpdatesScopeDepth, then we can assume the 'other' one has warned
611
- console.error(
612
- 'You seem to have overlapping act() calls, this is not supported. ' +
613
- 'Be sure to await previous act() calls before making a new one. ',
614
- );
615
- }
616
- }
617
- }
618
-
619
- let result;
620
- try {
621
- result = batchedUpdates(callback);
622
- } catch (error) {
623
- // on sync errors, we still want to 'cleanup' and decrement actingUpdatesScopeDepth
624
- onDone();
625
- throw error;
626
- }
627
-
628
- if (
629
- result !== null &&
630
- typeof result === 'object' &&
631
- typeof result.then === 'function'
632
- ) {
633
- // setup a boolean that gets set to true only
634
- // once this act() call is await-ed
635
- let called = false;
636
- if (__DEV__) {
637
- if (typeof Promise !== 'undefined') {
638
- //eslint-disable-next-line no-undef
639
- Promise.resolve()
640
- .then(() => {})
641
- .then(() => {
642
- if (called === false) {
643
- console.error(
644
- 'You called act(async () => ...) without await. ' +
645
- 'This could lead to unexpected testing behaviour, interleaving multiple act ' +
646
- 'calls and mixing their scopes. You should - await act(async () => ...);',
647
- );
648
- }
649
- });
650
- }
651
- }
652
-
653
- // in the async case, the returned thenable runs the callback, flushes
654
- // effects and microtasks in a loop until flushPassiveEffects() === false,
655
- // and cleans up
656
- return {
657
- then(resolve: () => void, reject: (?Error) => void) {
658
- called = true;
659
- result.then(
660
- () => {
661
- if (
662
- actingUpdatesScopeDepth > 1 ||
663
- (isSchedulerMocked === true &&
664
- previousIsSomeRendererActing === true)
665
- ) {
666
- onDone();
667
- resolve();
668
- return;
669
- }
670
- // we're about to exit the act() scope,
671
- // now's the time to flush tasks/effects
672
- flushWorkAndMicroTasks((err: ?Error) => {
673
- onDone();
674
- if (err) {
675
- reject(err);
676
- } else {
677
- resolve();
678
- }
679
- });
680
- },
681
- err => {
682
- onDone();
683
- reject(err);
684
- },
685
- );
686
- },
687
- };
688
- } else {
689
- if (__DEV__) {
690
- if (result !== undefined) {
691
- console.error(
692
- 'The callback passed to act(...) function ' +
693
- 'must return undefined, or a Promise. You returned %s',
694
- result,
695
- );
696
- }
697
- }
698
-
699
- // flush effects until none remain, and cleanup
700
- try {
701
- if (
702
- actingUpdatesScopeDepth === 1 &&
703
- (isSchedulerMocked === false || previousIsSomeRendererActing === false)
704
- ) {
705
- // we're about to exit the act() scope,
706
- // now's the time to flush effects
707
- flushWork();
708
- }
709
- onDone();
710
- } catch (err) {
711
- onDone();
712
- throw err;
713
- }
714
-
715
- // in the sync case, the returned thenable only warns *if* await-ed
716
- return {
717
- then(resolve: () => void) {
718
- if (__DEV__) {
719
- console.error(
720
- 'Do not await the result of calling act(...) with sync logic, it is not a Promise.',
721
- );
722
- }
723
- resolve();
724
- },
725
- };
726
- }
727
-}
46
+ createContainer as createContainer_new,
47
+ updateContainer as updateContainer_new,
48
+ batchedEventUpdates as batchedEventUpdates_new,
49
+ batchedUpdates as batchedUpdates_new,
50
+ unbatchedUpdates as unbatchedUpdates_new,
51
+ deferredUpdates as deferredUpdates_new,
52
+ syncUpdates as syncUpdates_new,
53
+ discreteUpdates as discreteUpdates_new,
54
+ flushDiscreteUpdates as flushDiscreteUpdates_new,
55
+ flushControlled as flushControlled_new,
56
+ flushSync as flushSync_new,
57
+ flushPassiveEffects as flushPassiveEffects_new,
58
+ IsThisRendererActing as IsThisRendererActing_new,
59
+ getPublicRootInstance as getPublicRootInstance_new,
60
+ attemptSynchronousHydration as attemptSynchronousHydration_new,
61
+ attemptUserBlockingHydration as attemptUserBlockingHydration_new,
62
+ attemptContinuousHydration as attemptContinuousHydration_new,
63
+ attemptHydrationAtCurrentPriority as attemptHydrationAtCurrentPriority_new,
64
+ findHostInstance as findHostInstance_new,
65
+ findHostInstanceWithWarning as findHostInstanceWithWarning_new,
66
+ findHostInstanceWithNoPortals as findHostInstanceWithNoPortals_new,
67
+ shouldSuspend as shouldSuspend_new,
68
+ injectIntoDevTools as injectIntoDevTools_new,
69
+ act as act_new,
70
+} from './ReactFiberReconciler.old';
71
+
72
+export const createContainer = enableNewReconciler
73
+ ? createContainer_new
74
+ : createContainer_old;
75
+export const updateContainer = enableNewReconciler
76
+ ? updateContainer_new
77
+ : updateContainer_old;
78
+export const batchedEventUpdates = enableNewReconciler
79
+ ? batchedEventUpdates_new
80
+ : batchedEventUpdates_old;
81
+export const batchedUpdates = enableNewReconciler
82
+ ? batchedUpdates_new
83
+ : batchedUpdates_old;
84
+export const unbatchedUpdates = enableNewReconciler
85
+ ? unbatchedUpdates_new
86
+ : unbatchedUpdates_old;
87
+export const deferredUpdates = enableNewReconciler
88
+ ? deferredUpdates_new
89
+ : deferredUpdates_old;
90
+export const syncUpdates = enableNewReconciler
91
+ ? syncUpdates_new
92
+ : syncUpdates_old;
93
+export const discreteUpdates = enableNewReconciler
94
+ ? discreteUpdates_new
95
+ : discreteUpdates_old;
96
+export const flushDiscreteUpdates = enableNewReconciler
97
+ ? flushDiscreteUpdates_new
98
+ : flushDiscreteUpdates_old;
99
+export const flushControlled = enableNewReconciler
100
+ ? flushControlled_new
101
+ : flushControlled_old;
102
+export const flushSync = enableNewReconciler ? flushSync_new : flushSync_old;
103
+export const flushPassiveEffects = enableNewReconciler
104
+ ? flushPassiveEffects_new
105
+ : flushPassiveEffects_old;
106
+export const IsThisRendererActing = enableNewReconciler
107
+ ? IsThisRendererActing_new
108
+ : IsThisRendererActing_old;
109
+export const getPublicRootInstance = enableNewReconciler
110
+ ? getPublicRootInstance_new
111
+ : getPublicRootInstance_old;
112
+export const attemptSynchronousHydration = enableNewReconciler
113
+ ? attemptSynchronousHydration_new
114
+ : attemptSynchronousHydration_old;
115
+export const attemptUserBlockingHydration = enableNewReconciler
116
+ ? attemptUserBlockingHydration_new
117
+ : attemptUserBlockingHydration_old;
118
+export const attemptContinuousHydration = enableNewReconciler
119
+ ? attemptContinuousHydration_new
120
+ : attemptContinuousHydration_old;
121
+export const attemptHydrationAtCurrentPriority = enableNewReconciler
122
+ ? attemptHydrationAtCurrentPriority_new
123
+ : attemptHydrationAtCurrentPriority_old;
124
+export const findHostInstance = enableNewReconciler
125
+ ? findHostInstance_new
126
+ : findHostInstance_old;
127
+export const findHostInstanceWithWarning = enableNewReconciler
128
+ ? findHostInstanceWithWarning_new
129
+ : findHostInstanceWithWarning_old;
130
+export const findHostInstanceWithNoPortals = enableNewReconciler
131
+ ? findHostInstanceWithNoPortals_new
132
+ : findHostInstanceWithNoPortals_old;
133
+export const shouldSuspend = enableNewReconciler
134
+ ? shouldSuspend_new
135
+ : shouldSuspend_old;
136
+export const injectIntoDevTools = enableNewReconciler
137
+ ? injectIntoDevTools_new
138
+ : injectIntoDevTools_old;
139
+export const act = enableNewReconciler ? act_new : act_old;