diff --git a/packages/react-devtools-scheduling-profiler/src/constants.js b/packages/react-devtools-scheduling-profiler/src/constants.js
index e5f9336d73e78..2e463ae632d95 100644
--- a/packages/react-devtools-scheduling-profiler/src/constants.js
+++ b/packages/react-devtools-scheduling-profiler/src/constants.js
@@ -11,6 +11,5 @@ export {
COMFORTABLE_LINE_HEIGHT,
COMPACT_LINE_HEIGHT,
} from 'react-devtools-shared/src/constants.js';
-import {TotalLanes} from 'react-reconciler/src/ReactFiberLane.new';
-export const REACT_TOTAL_NUM_LANES = TotalLanes;
+export const REACT_TOTAL_NUM_LANES = 31;
diff --git a/packages/react-dom/src/__tests__/ReactDOMServerPartialHydration-test.internal.js b/packages/react-dom/src/__tests__/ReactDOMServerPartialHydration-test.internal.js
index 67d1a29f0ab03..2ad221d5fbcb6 100644
--- a/packages/react-dom/src/__tests__/ReactDOMServerPartialHydration-test.internal.js
+++ b/packages/react-dom/src/__tests__/ReactDOMServerPartialHydration-test.internal.js
@@ -380,6 +380,7 @@ describe('ReactDOMServerPartialHydration', () => {
resolve();
await promise;
Scheduler.unstable_flushAll();
+ await null;
jest.runAllTimers();
// We should now have hydrated with a ref on the existing span.
diff --git a/packages/react-dom/src/__tests__/ReactServerRenderingHydration-test.js b/packages/react-dom/src/__tests__/ReactServerRenderingHydration-test.js
index fea9d79b4735d..a361e55a7f8fc 100644
--- a/packages/react-dom/src/__tests__/ReactServerRenderingHydration-test.js
+++ b/packages/react-dom/src/__tests__/ReactServerRenderingHydration-test.js
@@ -488,6 +488,7 @@ describe('ReactDOMServerHydration', () => {
jest.runAllTimers();
await Promise.resolve();
Scheduler.unstable_flushAll();
+ await null;
expect(element.textContent).toBe('Hello world');
});
diff --git a/packages/react-is/index.experimental.js b/packages/react-is/index.experimental.js
new file mode 100644
index 0000000000000..560283842b594
--- /dev/null
+++ b/packages/react-is/index.experimental.js
@@ -0,0 +1,41 @@
+/**
+ * Copyright (c) Facebook, Inc. and its affiliates.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ *
+ * @flow
+ */
+
+'use strict';
+
+export {
+ isValidElementType,
+ typeOf,
+ ContextConsumer,
+ ContextProvider,
+ Element,
+ ForwardRef,
+ Fragment,
+ Lazy,
+ Memo,
+ Portal,
+ Profiler,
+ StrictMode,
+ Suspense,
+ unstable_SuspenseList,
+ isAsyncMode,
+ isConcurrentMode,
+ isContextConsumer,
+ isContextProvider,
+ isElement,
+ isForwardRef,
+ isFragment,
+ isLazy,
+ isMemo,
+ isPortal,
+ isProfiler,
+ isStrictMode,
+ isSuspense,
+ unstable_isSuspenseList,
+} from './src/ReactIs';
diff --git a/packages/react-is/index.stable.js b/packages/react-is/index.stable.js
new file mode 100644
index 0000000000000..ad64178a1c537
--- /dev/null
+++ b/packages/react-is/index.stable.js
@@ -0,0 +1,39 @@
+/**
+ * Copyright (c) Facebook, Inc. and its affiliates.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ *
+ * @flow
+ */
+
+'use strict';
+
+export {
+ isValidElementType,
+ typeOf,
+ ContextConsumer,
+ ContextProvider,
+ Element,
+ ForwardRef,
+ Fragment,
+ Lazy,
+ Memo,
+ Portal,
+ Profiler,
+ StrictMode,
+ Suspense,
+ isAsyncMode,
+ isConcurrentMode,
+ isContextConsumer,
+ isContextProvider,
+ isElement,
+ isForwardRef,
+ isFragment,
+ isLazy,
+ isMemo,
+ isPortal,
+ isProfiler,
+ isStrictMode,
+ isSuspense,
+} from './src/ReactIs';
diff --git a/packages/react-is/src/ReactIs.js b/packages/react-is/src/ReactIs.js
index 2f132ba5de9a0..1958043bb2243 100644
--- a/packages/react-is/src/ReactIs.js
+++ b/packages/react-is/src/ReactIs.js
@@ -72,6 +72,7 @@ export const Portal = REACT_PORTAL_TYPE;
export const Profiler = REACT_PROFILER_TYPE;
export const StrictMode = REACT_STRICT_MODE_TYPE;
export const Suspense = REACT_SUSPENSE_TYPE;
+export const unstable_SuspenseList = REACT_SUSPENSE_LIST_TYPE;
export {isValidElementType};
@@ -142,3 +143,6 @@ export function isStrictMode(object: any) {
export function isSuspense(object: any) {
return typeOf(object) === REACT_SUSPENSE_TYPE;
}
+export function unstable_isSuspenseList(object: any) {
+ return typeOf(object) === REACT_SUSPENSE_LIST_TYPE;
+}
diff --git a/packages/react-is/src/__tests__/ReactIs-test.js b/packages/react-is/src/__tests__/ReactIs-test.js
index cddd479c4344e..e054cdbc4d485 100644
--- a/packages/react-is/src/__tests__/ReactIs-test.js
+++ b/packages/react-is/src/__tests__/ReactIs-test.js
@@ -186,6 +186,24 @@ describe('ReactIs', () => {
expect(ReactIs.isSuspense(
)).toBe(false);
});
+ // @gate experimental
+ it('should identify suspense list', () => {
+ expect(ReactIs.isValidElementType(React.unstable_SuspenseList)).toBe(true);
+ expect(ReactIs.typeOf()).toBe(
+ ReactIs.unstable_SuspenseList,
+ );
+ expect(
+ ReactIs.unstable_isSuspenseList(),
+ ).toBe(true);
+ expect(
+ ReactIs.unstable_isSuspenseList({type: ReactIs.unstable_SuspenseList}),
+ ).toBe(false);
+ expect(ReactIs.unstable_isSuspenseList('React.unstable_SuspenseList')).toBe(
+ false,
+ );
+ expect(ReactIs.unstable_isSuspenseList()).toBe(false);
+ });
+
it('should identify profile root', () => {
expect(ReactIs.isValidElementType(React.Profiler)).toBe(true);
expect(
diff --git a/packages/react-native-renderer/src/ReactFabric.js b/packages/react-native-renderer/src/ReactFabric.js
index 03ad183c37df4..9761124e7da65 100644
--- a/packages/react-native-renderer/src/ReactFabric.js
+++ b/packages/react-native-renderer/src/ReactFabric.js
@@ -9,7 +9,7 @@
import type {HostComponent} from './ReactNativeTypes';
import type {ReactNodeList} from 'shared/ReactTypes';
-import type {ElementRef} from 'react';
+import type {ElementRef, Element, ElementType} from 'react';
import './ReactFabricInjection';
@@ -47,8 +47,8 @@ import getComponentName from 'shared/getComponentName';
const ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner;
-function findHostInstance_DEPRECATED(
- componentOrHandle: any,
+function findHostInstance_DEPRECATED(
+ componentOrHandle: ?(ElementRef | number),
): ?ElementRef> {
if (__DEV__) {
const owner = ReactCurrentOwner.current;
@@ -70,10 +70,14 @@ function findHostInstance_DEPRECATED(
if (componentOrHandle == null) {
return null;
}
+ // $FlowIssue Flow has hardcoded values for React DOM that don't work with RN
if (componentOrHandle._nativeTag) {
+ // $FlowIssue Flow has hardcoded values for React DOM that don't work with RN
return componentOrHandle;
}
+ // $FlowIssue Flow has hardcoded values for React DOM that don't work with RN
if (componentOrHandle.canonical && componentOrHandle.canonical._nativeTag) {
+ // $FlowIssue Flow has hardcoded values for React DOM that don't work with RN
return componentOrHandle.canonical;
}
let hostInstance;
@@ -194,10 +198,10 @@ function sendAccessibilityEvent(handle: any, eventType: string) {
}
function render(
- element: React$Element,
- containerTag: any,
- callback: ?Function,
-) {
+ element: Element,
+ containerTag: number,
+ callback: ?() => void,
+): ?ElementRef {
let root = roots.get(containerTag);
if (!root) {
@@ -208,6 +212,7 @@ function render(
}
updateContainer(element, root, null, callback);
+ // $FlowIssue Flow has hardcoded values for React DOM that don't work with RN
return getPublicRootInstance(root);
}
diff --git a/packages/react-native-renderer/src/ReactFabricHostConfig.js b/packages/react-native-renderer/src/ReactFabricHostConfig.js
index e06652048e3da..85eb2a741ffac 100644
--- a/packages/react-native-renderer/src/ReactFabricHostConfig.js
+++ b/packages/react-native-renderer/src/ReactFabricHostConfig.js
@@ -14,7 +14,7 @@ import type {
MeasureLayoutOnSuccessCallback,
MeasureOnSuccessCallback,
NativeMethods,
- ReactNativeBaseComponentViewConfig,
+ ViewConfig,
TouchedViewDataAtPoint,
} from './ReactNativeTypes';
@@ -111,13 +111,13 @@ if (registerEventHandler) {
*/
class ReactFabricHostComponent {
_nativeTag: number;
- viewConfig: ReactNativeBaseComponentViewConfig<>;
+ viewConfig: ViewConfig;
currentProps: Props;
_internalInstanceHandle: Object;
constructor(
tag: number,
- viewConfig: ReactNativeBaseComponentViewConfig<>,
+ viewConfig: ViewConfig,
props: Props,
internalInstanceHandle: Object,
) {
diff --git a/packages/react-native-renderer/src/ReactNativeAttributePayload.js b/packages/react-native-renderer/src/ReactNativeAttributePayload.js
index 5804d83b5dc59..fa1187bc339bc 100644
--- a/packages/react-native-renderer/src/ReactNativeAttributePayload.js
+++ b/packages/react-native-renderer/src/ReactNativeAttributePayload.js
@@ -49,7 +49,7 @@ function defaultDiffer(prevProp: mixed, nextProp: mixed): boolean {
function restoreDeletedValuesInNestedArray(
updatePayload: Object,
node: NestedNode,
- validAttributes: AttributeConfiguration<>,
+ validAttributes: AttributeConfiguration,
) {
if (Array.isArray(node)) {
let i = node.length;
@@ -107,7 +107,7 @@ function diffNestedArrayProperty(
updatePayload: null | Object,
prevArray: Array,
nextArray: Array,
- validAttributes: AttributeConfiguration<>,
+ validAttributes: AttributeConfiguration,
): null | Object {
const minLength =
prevArray.length < nextArray.length ? prevArray.length : nextArray.length;
@@ -145,7 +145,7 @@ function diffNestedProperty(
updatePayload: null | Object,
prevProp: NestedNode,
nextProp: NestedNode,
- validAttributes: AttributeConfiguration<>,
+ validAttributes: AttributeConfiguration,
): null | Object {
if (!updatePayload && prevProp === nextProp) {
// If no properties have been added, then we can bail out quickly on object
@@ -206,7 +206,7 @@ function diffNestedProperty(
function addNestedProperty(
updatePayload: null | Object,
nextProp: NestedNode,
- validAttributes: AttributeConfiguration<>,
+ validAttributes: AttributeConfiguration,
) {
if (!nextProp) {
return updatePayload;
@@ -236,7 +236,7 @@ function addNestedProperty(
function clearNestedProperty(
updatePayload: null | Object,
prevProp: NestedNode,
- validAttributes: AttributeConfiguration<>,
+ validAttributes: AttributeConfiguration,
): null | Object {
if (!prevProp) {
return updatePayload;
@@ -268,7 +268,7 @@ function diffProperties(
updatePayload: null | Object,
prevProps: Object,
nextProps: Object,
- validAttributes: AttributeConfiguration<>,
+ validAttributes: AttributeConfiguration,
): null | Object {
let attributeConfig;
let nextProp;
@@ -369,13 +369,13 @@ function diffProperties(
updatePayload,
prevProp,
nextProp,
- ((attributeConfig: any): AttributeConfiguration<>),
+ ((attributeConfig: any): AttributeConfiguration),
);
if (removedKeyCount > 0 && updatePayload) {
restoreDeletedValuesInNestedArray(
updatePayload,
nextProp,
- ((attributeConfig: any): AttributeConfiguration<>),
+ ((attributeConfig: any): AttributeConfiguration),
);
removedKeys = null;
}
@@ -426,7 +426,7 @@ function diffProperties(
updatePayload = clearNestedProperty(
updatePayload,
prevProp,
- ((attributeConfig: any): AttributeConfiguration<>),
+ ((attributeConfig: any): AttributeConfiguration),
);
}
}
@@ -439,7 +439,7 @@ function diffProperties(
function addProperties(
updatePayload: null | Object,
props: Object,
- validAttributes: AttributeConfiguration<>,
+ validAttributes: AttributeConfiguration,
): null | Object {
// TODO: Fast path
return diffProperties(updatePayload, emptyObject, props, validAttributes);
@@ -452,7 +452,7 @@ function addProperties(
function clearProperties(
updatePayload: null | Object,
prevProps: Object,
- validAttributes: AttributeConfiguration<>,
+ validAttributes: AttributeConfiguration,
): null | Object {
// TODO: Fast path
return diffProperties(updatePayload, prevProps, emptyObject, validAttributes);
@@ -460,7 +460,7 @@ function clearProperties(
export function create(
props: Object,
- validAttributes: AttributeConfiguration<>,
+ validAttributes: AttributeConfiguration,
): null | Object {
return addProperties(
null, // updatePayload
@@ -472,7 +472,7 @@ export function create(
export function diff(
prevProps: Object,
nextProps: Object,
- validAttributes: AttributeConfiguration<>,
+ validAttributes: AttributeConfiguration,
): null | Object {
return diffProperties(
null, // updatePayload
diff --git a/packages/react-native-renderer/src/ReactNativeFiberHostComponent.js b/packages/react-native-renderer/src/ReactNativeFiberHostComponent.js
index a4c90fa3f7be1..8048144431826 100644
--- a/packages/react-native-renderer/src/ReactNativeFiberHostComponent.js
+++ b/packages/react-native-renderer/src/ReactNativeFiberHostComponent.js
@@ -14,7 +14,7 @@ import type {
MeasureLayoutOnSuccessCallback,
MeasureOnSuccessCallback,
NativeMethods,
- ReactNativeBaseComponentViewConfig,
+ ViewConfig,
} from './ReactNativeTypes';
import type {Instance} from './ReactNativeHostConfig';
@@ -34,11 +34,11 @@ class ReactNativeFiberHostComponent {
_children: Array;
_nativeTag: number;
_internalFiberInstanceHandleDEV: Object;
- viewConfig: ReactNativeBaseComponentViewConfig<>;
+ viewConfig: ViewConfig;
constructor(
tag: number,
- viewConfig: ReactNativeBaseComponentViewConfig<>,
+ viewConfig: ViewConfig,
internalInstanceHandleDEV: Object,
) {
this._nativeTag = tag;
diff --git a/packages/react-native-renderer/src/ReactNativeRenderer.js b/packages/react-native-renderer/src/ReactNativeRenderer.js
index 673482d0175cd..547fdd2de5c52 100644
--- a/packages/react-native-renderer/src/ReactNativeRenderer.js
+++ b/packages/react-native-renderer/src/ReactNativeRenderer.js
@@ -9,6 +9,7 @@
import type {HostComponent} from './ReactNativeTypes';
import type {ReactNodeList} from 'shared/ReactTypes';
+import type {ElementRef, Element, ElementType} from 'react';
import './ReactNativeInjection';
@@ -193,10 +194,10 @@ function sendAccessibilityEvent(handle: any, eventType: string) {
}
function render(
- element: React$Element,
- containerTag: any,
- callback: ?Function,
-) {
+ element: Element,
+ containerTag: number,
+ callback: ?() => void,
+): ?ElementRef {
let root = roots.get(containerTag);
if (!root) {
@@ -207,6 +208,7 @@ function render(
}
updateContainer(element, root, null, callback);
+ // $FlowIssue Flow has hardcoded values for React DOM that don't work with RN
return getPublicRootInstance(root);
}
diff --git a/packages/react-native-renderer/src/ReactNativeTypes.js b/packages/react-native-renderer/src/ReactNativeTypes.js
index 8b4ab311bff79..462abeac94bee 100644
--- a/packages/react-native-renderer/src/ReactNativeTypes.js
+++ b/packages/react-native-renderer/src/ReactNativeTypes.js
@@ -5,10 +5,10 @@
* LICENSE file in the root directory of this source tree.
*
* @format
- * @flow
+ * @flow strict
*/
-import type {ElementRef, AbstractComponent} from 'react';
+import type {ElementRef, ElementType, Element, AbstractComponent} from 'react';
export type MeasureOnSuccessCallback = (
x: number,
@@ -33,49 +33,66 @@ export type MeasureLayoutOnSuccessCallback = (
height: number,
) => void;
-type AttributeType =
+type AttributeType =
| true
| $ReadOnly<{|
- diff?: (arg1: T, arg2: T) => boolean,
- process?: (arg1: any) => any,
+ diff?: (arg1: T, arg2: T) => boolean,
+ process?: (arg1: V) => T,
|}>;
-export type AttributeConfiguration<
- TProps = string,
- TStyleProps = string,
-> = $ReadOnly<{
- [propName: TProps]: AttributeType,
- style: $ReadOnly<{[propName: TStyleProps]: AttributeType, ...}>,
+// We either force that `diff` and `process` always use mixed,
+// or we allow them to define specific types and use this hack
+type AnyAttributeType = AttributeType<$FlowFixMe, $FlowFixMe>;
+
+export type AttributeConfiguration = $ReadOnly<{
+ [propName: string]: AnyAttributeType,
+ style: $ReadOnly<{
+ [propName: string]: AnyAttributeType,
+ ...,
+ }>,
+ ...
+}>;
+
+type PartialAttributeConfiguration = $ReadOnly<{
+ [propName: string]: AnyAttributeType,
+ style?: $ReadOnly<{
+ [propName: string]: AnyAttributeType,
+ ...,
+ }>,
...
}>;
-export type ReactNativeBaseComponentViewConfig<
- TProps = string,
- TStyleProps = string,
-> = $ReadOnly<{|
- baseModuleName?: string,
+export type ViewConfig = $ReadOnly<{
+ Commands?: $ReadOnly<{[commandName: string]: number, ...}>,
+ Constants?: $ReadOnly<{[name: string]: mixed, ...}>,
+ Manager?: string,
+ NativeProps?: $ReadOnly<{[propName: string]: string, ...}>,
+ baseModuleName?: ?string,
bubblingEventTypes?: $ReadOnly<{
- [eventName: string]: $ReadOnly<{|
- phasedRegistrationNames: $ReadOnly<{|
+ [eventName: string]: $ReadOnly<{
+ phasedRegistrationNames: $ReadOnly<{
captured: string,
bubbled: string,
- |}>,
- |}>,
+ }>,
+ }>,
...,
}>,
- Commands?: $ReadOnly<{[commandName: string]: number, ...}>,
directEventTypes?: $ReadOnly<{
- [eventName: string]: $ReadOnly<{|
+ [eventName: string]: $ReadOnly<{
registrationName: string,
- |}>,
+ }>,
...,
}>,
- NativeProps?: $ReadOnly<{[propName: string]: string, ...}>,
uiViewClassName: string,
- validAttributes: AttributeConfiguration,
-|}>;
+ validAttributes: AttributeConfiguration,
+}>;
-export type ViewConfigGetter = () => ReactNativeBaseComponentViewConfig<>;
+export type PartialViewConfig = $ReadOnly<{
+ bubblingEventTypes?: $PropertyType,
+ directEventTypes?: $PropertyType,
+ uiViewClassName: string,
+ validAttributes?: PartialAttributeConfiguration,
+}>;
export type NativeMethods = {
blur(): void,
@@ -87,7 +104,7 @@ export type NativeMethods = {
onSuccess: MeasureLayoutOnSuccessCallback,
onFail?: () => void,
): void,
- setNativeProps(nativeProps: Object): void,
+ setNativeProps(nativeProps: {...}): void,
...
};
@@ -111,9 +128,11 @@ type InspectorDataSource = $ReadOnly<{|
|}>;
type InspectorDataGetter = (
- (componentOrHandle: any) => ?number,
+ (
+ componentOrHandle: ElementRef | number,
+ ) => ?number,
) => $ReadOnly<{|
- measure: Function,
+ measure: (callback: MeasureOnSuccessCallback) => void,
props: InspectorDataProps,
source: InspectorDataSource,
|}>;
@@ -145,62 +164,65 @@ export type TouchedViewDataAtPoint = $ReadOnly<{|
* Provide minimal Flow typing for the high-level RN API and call it a day.
*/
export type ReactNativeType = {
- findHostInstance_DEPRECATED(
- componentOrHandle: any,
+ findHostInstance_DEPRECATED(
+ componentOrHandle: ?(ElementRef | number),
): ?ElementRef>,
- findNodeHandle(componentOrHandle: any): ?number,
+ findNodeHandle(
+ componentOrHandle: ?(ElementRef | number),
+ ): ?number,
dispatchCommand(
handle: ElementRef>,
command: string,
- args: Array,
+ args: Array,
): void,
sendAccessibilityEvent(
handle: ElementRef>,
eventType: string,
): void,
render(
- element: React$Element,
- containerTag: any,
- callback: ?Function,
- ): any,
- unmountComponentAtNode(containerTag: number): any,
- unmountComponentAtNodeAndRemoveContainer(containerTag: number): any,
- // TODO (bvaughn) Add types
- unstable_batchedUpdates: any,
+ element: Element,
+ containerTag: number,
+ callback: ?() => void,
+ ): ?ElementRef,
+ unmountComponentAtNode(containerTag: number): void,
+ unmountComponentAtNodeAndRemoveContainer(containerTag: number): void,
+ unstable_batchedUpdates: (fn: (T) => void, bookkeeping: T) => void,
__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED: SecretInternalsType,
...
};
export type ReactFabricType = {
- findHostInstance_DEPRECATED(
- componentOrHandle: any,
+ findHostInstance_DEPRECATED(
+ componentOrHandle: ?(ElementRef | number),
): ?ElementRef>,
- findNodeHandle(componentOrHandle: any): ?number,
+ findNodeHandle(
+ componentOrHandle: ?(ElementRef | number),
+ ): ?number,
dispatchCommand(
handle: ElementRef>,
command: string,
- args: Array,
+ args: Array,
): void,
sendAccessibilityEvent(
handle: ElementRef>,
eventType: string,
): void,
render(
- element: React$Element,
- containerTag: any,
- callback: ?Function,
- ): any,
- unmountComponentAtNode(containerTag: number): any,
+ element: Element,
+ containerTag: number,
+ callback: ?() => void,
+ ): ?ElementRef,
+ unmountComponentAtNode(containerTag: number): void,
...
};
export type ReactNativeEventTarget = {
- node: Object,
+ node: {...},
canonical: {
_nativeTag: number,
- viewConfig: ReactNativeBaseComponentViewConfig<>,
- currentProps: Object,
- _internalInstanceHandle: Object,
+ viewConfig: ViewConfig,
+ currentProps: {...},
+ _internalInstanceHandle: {...},
...
},
...
diff --git a/packages/react-reconciler/src/SchedulerWithReactIntegration.new.js b/packages/react-reconciler/src/SchedulerWithReactIntegration.new.js
index 36dbc704fc7cd..1c13e3a8fda90 100644
--- a/packages/react-reconciler/src/SchedulerWithReactIntegration.new.js
+++ b/packages/react-reconciler/src/SchedulerWithReactIntegration.new.js
@@ -16,6 +16,7 @@ import {__interactionsRef} from 'scheduler/tracing';
import {
enableSchedulerTracing,
decoupleUpdatePriorityFromScheduler,
+ enableSyncMicroTasks,
} from 'shared/ReactFeatureFlags';
import invariant from 'shared/invariant';
import {
@@ -23,6 +24,7 @@ import {
getCurrentUpdateLanePriority,
setCurrentUpdateLanePriority,
} from './ReactFiberLane.new';
+import {scheduleMicrotask, supportsMicrotasks} from './ReactFiberHostConfig';
const {
unstable_runWithPriority: Scheduler_runWithPriority,
@@ -144,13 +146,19 @@ export function scheduleSyncCallback(callback: SchedulerCallback) {
// the next tick, or earlier if something calls `flushSyncCallbackQueue`.
if (syncQueue === null) {
syncQueue = [callback];
- // Flush the queue in the next tick, at the earliest.
+
// TODO: Figure out how to remove this It's only here as a last resort if we
// forget to explicitly flush.
- immediateQueueCallbackNode = Scheduler_scheduleCallback(
- Scheduler_ImmediatePriority,
- flushSyncCallbackQueueImpl,
- );
+ if (enableSyncMicroTasks && supportsMicrotasks) {
+ // Flush the queue in a microtask.
+ scheduleMicrotask(flushSyncCallbackQueueImpl);
+ } else {
+ // Flush the queue in the next tick.
+ immediateQueueCallbackNode = Scheduler_scheduleCallback(
+ Scheduler_ImmediatePriority,
+ flushSyncCallbackQueueImpl,
+ );
+ }
} else {
// Push onto existing queue. Don't need to schedule a callback because
// we already scheduled one when we created the queue.
diff --git a/packages/react-reconciler/src/SchedulerWithReactIntegration.old.js b/packages/react-reconciler/src/SchedulerWithReactIntegration.old.js
index 1d309df4020f1..5c4451499ca5b 100644
--- a/packages/react-reconciler/src/SchedulerWithReactIntegration.old.js
+++ b/packages/react-reconciler/src/SchedulerWithReactIntegration.old.js
@@ -16,6 +16,7 @@ import {__interactionsRef} from 'scheduler/tracing';
import {
enableSchedulerTracing,
decoupleUpdatePriorityFromScheduler,
+ enableSyncMicroTasks,
} from 'shared/ReactFeatureFlags';
import invariant from 'shared/invariant';
import {
@@ -23,6 +24,7 @@ import {
getCurrentUpdateLanePriority,
setCurrentUpdateLanePriority,
} from './ReactFiberLane.old';
+import {scheduleMicrotask, supportsMicrotasks} from './ReactFiberHostConfig';
const {
unstable_runWithPriority: Scheduler_runWithPriority,
@@ -144,13 +146,19 @@ export function scheduleSyncCallback(callback: SchedulerCallback) {
// the next tick, or earlier if something calls `flushSyncCallbackQueue`.
if (syncQueue === null) {
syncQueue = [callback];
- // Flush the queue in the next tick, at the earliest.
+
// TODO: Figure out how to remove this It's only here as a last resort if we
// forget to explicitly flush.
- immediateQueueCallbackNode = Scheduler_scheduleCallback(
- Scheduler_ImmediatePriority,
- flushSyncCallbackQueueImpl,
- );
+ if (enableSyncMicroTasks && supportsMicrotasks) {
+ // Flush the queue in a microtask.
+ scheduleMicrotask(flushSyncCallbackQueueImpl);
+ } else {
+ // Flush the queue in the next tick.
+ immediateQueueCallbackNode = Scheduler_scheduleCallback(
+ Scheduler_ImmediatePriority,
+ flushSyncCallbackQueueImpl,
+ );
+ }
} else {
// Push onto existing queue. Don't need to schedule a callback because
// we already scheduled one when we created the queue.
diff --git a/packages/react-reconciler/src/__tests__/ReactExpiration-test.js b/packages/react-reconciler/src/__tests__/ReactExpiration-test.js
index 017c712bd814b..48ff50880f943 100644
--- a/packages/react-reconciler/src/__tests__/ReactExpiration-test.js
+++ b/packages/react-reconciler/src/__tests__/ReactExpiration-test.js
@@ -598,12 +598,13 @@ describe('ReactExpiration', () => {
// second one.
Scheduler.unstable_advanceTime(1000);
// Attempt to interrupt with a high pri update.
- updateHighPri();
+ await ReactNoop.act(async () => {
+ updateHighPri();
+ });
- // The first update expired, so first will finish it without
- // interrupting. But not the second update, which hasn't expired yet.
- expect(Scheduler).toFlushExpired(['Sibling']);
- expect(Scheduler).toFlushAndYield([
+ expect(Scheduler).toHaveYielded([
+ // The first update expired
+ 'Sibling',
// Then render the high pri update
'High pri: 1',
'Normal pri: 1',
diff --git a/packages/react-reconciler/src/__tests__/ReactHooksWithNoopRenderer-test.js b/packages/react-reconciler/src/__tests__/ReactHooksWithNoopRenderer-test.js
index bf5503feb4902..4c7d308a9c909 100644
--- a/packages/react-reconciler/src/__tests__/ReactHooksWithNoopRenderer-test.js
+++ b/packages/react-reconciler/src/__tests__/ReactHooksWithNoopRenderer-test.js
@@ -1792,7 +1792,7 @@ describe('ReactHooksWithNoopRenderer', () => {
it(
'in legacy mode, useEffect is deferred and updates finish synchronously ' +
'(in a single batch)',
- () => {
+ async () => {
function Counter(props) {
const [count, updateCount] = useState('(empty)');
useEffect(() => {
@@ -1807,10 +1807,12 @@ describe('ReactHooksWithNoopRenderer', () => {
}, [props.count]);
return ;
}
- act(() => {
+ await act(async () => {
ReactNoop.renderLegacySyncRoot();
+
// Even in legacy mode, effects are deferred until after paint
- expect(Scheduler).toFlushAndYieldThrough(['Count: (empty)']);
+ ReactNoop.flushSync();
+ expect(Scheduler).toHaveYielded(['Count: (empty)']);
expect(ReactNoop.getChildren()).toEqual([span('Count: (empty)')]);
});
diff --git a/packages/react-reconciler/src/__tests__/ReactIncrementalErrorHandling-test.internal.js b/packages/react-reconciler/src/__tests__/ReactIncrementalErrorHandling-test.internal.js
index f568191681b67..613fe89d63279 100644
--- a/packages/react-reconciler/src/__tests__/ReactIncrementalErrorHandling-test.internal.js
+++ b/packages/react-reconciler/src/__tests__/ReactIncrementalErrorHandling-test.internal.js
@@ -1400,6 +1400,10 @@ describe('ReactIncrementalErrorHandling', () => {
'BrokenRenderAndUnmount componentWillUnmount',
]);
expect(ReactNoop.getChildren()).toEqual([]);
+
+ expect(() => {
+ ReactNoop.flushSync();
+ }).toThrow('One does not simply unmount me.');
});
it('does not interrupt unmounting if detaching a ref throws', () => {
diff --git a/packages/react-reconciler/src/__tests__/ReactOffscreen-test.js b/packages/react-reconciler/src/__tests__/ReactOffscreen-test.js
index e830fa2b24ddf..b3f14e6ad1efc 100644
--- a/packages/react-reconciler/src/__tests__/ReactOffscreen-test.js
+++ b/packages/react-reconciler/src/__tests__/ReactOffscreen-test.js
@@ -98,8 +98,11 @@ describe('ReactOffscreen', () => {
>,
);
+
+ ReactNoop.flushSync();
+
// Should not defer the hidden tree
- expect(Scheduler).toFlushUntilNextPaint(['A', 'Outside']);
+ expect(Scheduler).toHaveYielded(['A', 'Outside']);
});
expect(root).toMatchRenderedOutput(
<>
diff --git a/packages/react-reconciler/src/__tests__/ReactSchedulerIntegration-test.js b/packages/react-reconciler/src/__tests__/ReactSchedulerIntegration-test.js
index 4292333293e82..ab9995d01cb5f 100644
--- a/packages/react-reconciler/src/__tests__/ReactSchedulerIntegration-test.js
+++ b/packages/react-reconciler/src/__tests__/ReactSchedulerIntegration-test.js
@@ -569,9 +569,11 @@ describe(
ReactNoop.render();
});
+ ReactNoop.flushSync();
+
// Because the render expired, React should finish the tree without
// consulting `shouldYield` again
- expect(Scheduler).toFlushExpired(['B', 'C']);
+ expect(Scheduler).toHaveYielded(['B', 'C']);
});
});
},
diff --git a/packages/react-reconciler/src/__tests__/ReactSuspenseList-test.js b/packages/react-reconciler/src/__tests__/ReactSuspenseList-test.js
index de74c18e5ca6a..2cdc2621fbe9a 100644
--- a/packages/react-reconciler/src/__tests__/ReactSuspenseList-test.js
+++ b/packages/react-reconciler/src/__tests__/ReactSuspenseList-test.js
@@ -292,9 +292,11 @@ describe('ReactSuspenseList', () => {
>,
);
- await C.resolve();
+ await ReactNoop.act(async () => {
+ C.resolve();
+ });
- expect(Scheduler).toFlushAndYield(['C']);
+ expect(Scheduler).toHaveYielded(['C']);
expect(ReactNoop).toMatchRenderedOutput(
<>
@@ -304,9 +306,11 @@ describe('ReactSuspenseList', () => {
>,
);
- await B.resolve();
+ await ReactNoop.act(async () => {
+ B.resolve();
+ });
- expect(Scheduler).toFlushAndYield(['B']);
+ expect(Scheduler).toHaveYielded(['B']);
expect(ReactNoop).toMatchRenderedOutput(
<>
diff --git a/packages/react-reconciler/src/__tests__/ReactSuspensePlaceholder-test.internal.js b/packages/react-reconciler/src/__tests__/ReactSuspensePlaceholder-test.internal.js
index d40f56380b7e8..b6e34104ad61f 100644
--- a/packages/react-reconciler/src/__tests__/ReactSuspensePlaceholder-test.internal.js
+++ b/packages/react-reconciler/src/__tests__/ReactSuspensePlaceholder-test.internal.js
@@ -310,7 +310,7 @@ describe('ReactSuspensePlaceholder', () => {
});
describe('when suspending during mount', () => {
- it('properly accounts for base durations when a suspended times out in a legacy tree', () => {
+ it('properly accounts for base durations when a suspended times out in a legacy tree', async () => {
ReactNoop.renderLegacySyncRoot();
expect(Scheduler).toHaveYielded([
'App',
@@ -331,7 +331,10 @@ describe('ReactSuspensePlaceholder', () => {
jest.advanceTimersByTime(1000);
expect(Scheduler).toHaveYielded(['Promise resolved [Loaded]']);
- expect(Scheduler).toFlushExpired(['Loaded']);
+
+ ReactNoop.flushSync();
+
+ expect(Scheduler).toHaveYielded(['Loaded']);
expect(ReactNoop).toMatchRenderedOutput('LoadedText');
expect(onRender).toHaveBeenCalledTimes(2);
@@ -378,7 +381,7 @@ describe('ReactSuspensePlaceholder', () => {
});
describe('when suspending during update', () => {
- it('properly accounts for base durations when a suspended times out in a legacy tree', () => {
+ it('properly accounts for base durations when a suspended times out in a legacy tree', async () => {
ReactNoop.renderLegacySyncRoot(
,
);
@@ -427,7 +430,10 @@ describe('ReactSuspensePlaceholder', () => {
jest.advanceTimersByTime(1000);
expect(Scheduler).toHaveYielded(['Promise resolved [Loaded]']);
- expect(Scheduler).toFlushExpired(['Loaded']);
+
+ ReactNoop.flushSync();
+
+ expect(Scheduler).toHaveYielded(['Loaded']);
expect(ReactNoop).toMatchRenderedOutput('LoadedNew');
expect(onRender).toHaveBeenCalledTimes(4);
diff --git a/packages/react-reconciler/src/__tests__/ReactSuspenseWithNoopRenderer-test.js b/packages/react-reconciler/src/__tests__/ReactSuspenseWithNoopRenderer-test.js
index 20971e9f58e91..8e8a512dacf41 100644
--- a/packages/react-reconciler/src/__tests__/ReactSuspenseWithNoopRenderer-test.js
+++ b/packages/react-reconciler/src/__tests__/ReactSuspenseWithNoopRenderer-test.js
@@ -1088,9 +1088,11 @@ describe('ReactSuspenseWithNoopRenderer', () => {
expect(Scheduler).toHaveYielded(['Suspend! [Result]', 'Loading...']);
expect(ReactNoop.getChildren()).toEqual([span('Loading...')]);
- await resolveText('Result');
+ await ReactNoop.act(async () => {
+ resolveText('Result');
+ });
- expect(Scheduler).toFlushExpired(['Result']);
+ expect(Scheduler).toHaveYielded(['Result']);
expect(ReactNoop.getChildren()).toEqual([span('Result')]);
});
@@ -1156,8 +1158,10 @@ describe('ReactSuspenseWithNoopRenderer', () => {
>,
);
- await resolveText('Step: 2');
- expect(Scheduler).toFlushExpired(['Step: 2']);
+ await ReactNoop.act(async () => {
+ resolveText('Step: 2');
+ });
+ expect(Scheduler).toHaveYielded(['Step: 2']);
expect(ReactNoop).toMatchRenderedOutput(
<>
@@ -1227,9 +1231,11 @@ describe('ReactSuspenseWithNoopRenderer', () => {
>,
);
- await resolveText('B');
+ await ReactNoop.act(async () => {
+ resolveText('B');
+ });
- expect(Scheduler).toFlushExpired(['B']);
+ expect(Scheduler).toHaveYielded(['B']);
expect(ReactNoop).toMatchRenderedOutput(
<>
@@ -1271,9 +1277,11 @@ describe('ReactSuspenseWithNoopRenderer', () => {
]);
expect(ReactNoop.getChildren()).toEqual([span('Loading...')]);
- await resolveText('Hi');
+ await ReactNoop.act(async () => {
+ resolveText('Hi');
+ });
- expect(Scheduler).toFlushExpired([
+ expect(Scheduler).toHaveYielded([
'constructor',
'Hi',
'componentDidMount',
@@ -1316,8 +1324,10 @@ describe('ReactSuspenseWithNoopRenderer', () => {
'Loading...',
]);
expect(ReactNoop.getChildren()).toEqual([span('Loading...')]);
- await resolveText('Hi');
- expect(Scheduler).toFlushExpired(['Hi']);
+ await ReactNoop.act(async () => {
+ resolveText('Hi');
+ });
+ expect(Scheduler).toHaveYielded(['Hi']);
expect(ReactNoop.getChildren()).toEqual([span('Hi')]);
});
@@ -1360,8 +1370,10 @@ describe('ReactSuspenseWithNoopRenderer', () => {
>,
]);
- await resolveText('Hi');
- expect(Scheduler).toFlushExpired(['Hi']);
+ await ReactNoop.act(async () => {
+ resolveText('Hi');
+ });
+ expect(Scheduler).toHaveYielded(['Hi']);
});
} else {
// @gate enableCache
@@ -1401,9 +1413,11 @@ describe('ReactSuspenseWithNoopRenderer', () => {
'Child is hidden: true',
]);
- await resolveText('Hi');
+ await ReactNoop.act(async () => {
+ resolveText('Hi');
+ });
- expect(Scheduler).toFlushExpired(['Hi']);
+ expect(Scheduler).toHaveYielded(['Hi']);
});
}
@@ -1647,9 +1661,11 @@ describe('ReactSuspenseWithNoopRenderer', () => {
>,
);
- await resolveText('B');
+ await ReactNoop.act(async () => {
+ resolveText('B');
+ });
- expect(Scheduler).toFlushAndYield([
+ expect(Scheduler).toHaveYielded([
'B',
'Destroy Layout Effect [Loading...]',
'Layout Effect [B]',
@@ -1681,9 +1697,11 @@ describe('ReactSuspenseWithNoopRenderer', () => {
'Effect [Loading...]',
]);
- await resolveText('B2');
+ await ReactNoop.act(async () => {
+ resolveText('B2');
+ });
- expect(Scheduler).toFlushAndYield([
+ expect(Scheduler).toHaveYielded([
'B2',
'Destroy Layout Effect [Loading...]',
'Destroy Layout Effect [B]',
diff --git a/packages/react-reconciler/src/__tests__/useMutableSource-test.internal.js b/packages/react-reconciler/src/__tests__/useMutableSource-test.internal.js
index db4214bfd0656..cf1db2891e11d 100644
--- a/packages/react-reconciler/src/__tests__/useMutableSource-test.internal.js
+++ b/packages/react-reconciler/src/__tests__/useMutableSource-test.internal.js
@@ -1794,7 +1794,7 @@ describe('useMutableSource', () => {
});
// @gate experimental
- it('should not misidentify mutations after render as side effects', () => {
+ it('should not misidentify mutations after render as side effects', async () => {
const source = createSource('initial');
const mutableSource = createMutableSource(
source,
@@ -1811,15 +1811,16 @@ describe('useMutableSource', () => {
return null;
}
- act(() => {
+ await act(async () => {
ReactNoop.renderLegacySyncRoot(
,
);
- expect(Scheduler).toFlushAndYieldThrough([
- 'MutateDuringRead:initial',
- ]);
+ });
+ expect(Scheduler).toHaveYielded(['MutateDuringRead:initial']);
+
+ await act(async () => {
source.value = 'updated';
});
expect(Scheduler).toHaveYielded(['MutateDuringRead:updated']);
diff --git a/packages/shared/ReactFeatureFlags.js b/packages/shared/ReactFeatureFlags.js
index 953eb7cd56615..201546e822b20 100644
--- a/packages/shared/ReactFeatureFlags.js
+++ b/packages/shared/ReactFeatureFlags.js
@@ -155,4 +155,6 @@ export const disableSchedulerTimeoutInWorkLoop = false;
export const enableDiscreteEventMicroTasks = false;
+export const enableSyncMicroTasks = false;
+
export const enableNativeEventPriorityInference = false;
diff --git a/packages/shared/forks/ReactFeatureFlags.native-fb.js b/packages/shared/forks/ReactFeatureFlags.native-fb.js
index 2f4406b2ceafa..e0bff4b32f634 100644
--- a/packages/shared/forks/ReactFeatureFlags.native-fb.js
+++ b/packages/shared/forks/ReactFeatureFlags.native-fb.js
@@ -59,6 +59,7 @@ export const enableUseRefAccessWarning = false;
export const enableRecursiveCommitTraversal = false;
export const disableSchedulerTimeoutInWorkLoop = false;
export const enableDiscreteEventMicroTasks = false;
+export const enableSyncMicroTasks = false;
export const enableNativeEventPriorityInference = false;
// Flow magic to verify the exports of this file match the original version.
diff --git a/packages/shared/forks/ReactFeatureFlags.native-oss.js b/packages/shared/forks/ReactFeatureFlags.native-oss.js
index 35e1067646d94..a40b6e293c241 100644
--- a/packages/shared/forks/ReactFeatureFlags.native-oss.js
+++ b/packages/shared/forks/ReactFeatureFlags.native-oss.js
@@ -58,6 +58,7 @@ export const enableUseRefAccessWarning = false;
export const enableRecursiveCommitTraversal = false;
export const disableSchedulerTimeoutInWorkLoop = false;
export const enableDiscreteEventMicroTasks = false;
+export const enableSyncMicroTasks = false;
export const enableNativeEventPriorityInference = false;
// Flow magic to verify the exports of this file match the original version.
diff --git a/packages/shared/forks/ReactFeatureFlags.test-renderer.js b/packages/shared/forks/ReactFeatureFlags.test-renderer.js
index 67ecdb72983c7..97a26ddd86819 100644
--- a/packages/shared/forks/ReactFeatureFlags.test-renderer.js
+++ b/packages/shared/forks/ReactFeatureFlags.test-renderer.js
@@ -58,6 +58,7 @@ export const enableUseRefAccessWarning = false;
export const enableRecursiveCommitTraversal = false;
export const disableSchedulerTimeoutInWorkLoop = false;
export const enableDiscreteEventMicroTasks = false;
+export const enableSyncMicroTasks = false;
export const enableNativeEventPriorityInference = false;
// Flow magic to verify the exports of this file match the original version.
diff --git a/packages/shared/forks/ReactFeatureFlags.test-renderer.native.js b/packages/shared/forks/ReactFeatureFlags.test-renderer.native.js
index 9ed0be59689e7..1417670d7915c 100644
--- a/packages/shared/forks/ReactFeatureFlags.test-renderer.native.js
+++ b/packages/shared/forks/ReactFeatureFlags.test-renderer.native.js
@@ -58,6 +58,7 @@ export const enableUseRefAccessWarning = false;
export const enableRecursiveCommitTraversal = false;
export const disableSchedulerTimeoutInWorkLoop = false;
export const enableDiscreteEventMicroTasks = false;
+export const enableSyncMicroTasks = false;
export const enableNativeEventPriorityInference = false;
// Flow magic to verify the exports of this file match the original version.
diff --git a/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js b/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js
index 2e7513a8ddf15..17848a59376c6 100644
--- a/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js
+++ b/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js
@@ -58,6 +58,7 @@ export const enableUseRefAccessWarning = false;
export const enableRecursiveCommitTraversal = false;
export const disableSchedulerTimeoutInWorkLoop = false;
export const enableDiscreteEventMicroTasks = false;
+export const enableSyncMicroTasks = false;
export const enableNativeEventPriorityInference = false;
// Flow magic to verify the exports of this file match the original version.
diff --git a/packages/shared/forks/ReactFeatureFlags.testing.js b/packages/shared/forks/ReactFeatureFlags.testing.js
index 5a362e8a31419..ce73c8a870cf0 100644
--- a/packages/shared/forks/ReactFeatureFlags.testing.js
+++ b/packages/shared/forks/ReactFeatureFlags.testing.js
@@ -58,6 +58,7 @@ export const enableUseRefAccessWarning = false;
export const enableRecursiveCommitTraversal = false;
export const disableSchedulerTimeoutInWorkLoop = false;
export const enableDiscreteEventMicroTasks = false;
+export const enableSyncMicroTasks = false;
export const enableNativeEventPriorityInference = false;
// Flow magic to verify the exports of this file match the original version.
diff --git a/packages/shared/forks/ReactFeatureFlags.testing.www.js b/packages/shared/forks/ReactFeatureFlags.testing.www.js
index 54942f0c7cd2d..02dba8551fb1a 100644
--- a/packages/shared/forks/ReactFeatureFlags.testing.www.js
+++ b/packages/shared/forks/ReactFeatureFlags.testing.www.js
@@ -58,6 +58,7 @@ export const enableUseRefAccessWarning = false;
export const enableRecursiveCommitTraversal = false;
export const disableSchedulerTimeoutInWorkLoop = false;
export const enableDiscreteEventMicroTasks = false;
+export const enableSyncMicroTasks = false;
export const enableNativeEventPriorityInference = false;
// Flow magic to verify the exports of this file match the original version.
diff --git a/packages/shared/forks/ReactFeatureFlags.www-dynamic.js b/packages/shared/forks/ReactFeatureFlags.www-dynamic.js
index 1d9f89699f317..b75b80dbde650 100644
--- a/packages/shared/forks/ReactFeatureFlags.www-dynamic.js
+++ b/packages/shared/forks/ReactFeatureFlags.www-dynamic.js
@@ -57,4 +57,5 @@ export const enableUseRefAccessWarning = __VARIANT__;
export const enableProfilerNestedUpdateScheduledHook = __VARIANT__;
export const disableSchedulerTimeoutInWorkLoop = __VARIANT__;
export const enableDiscreteEventMicroTasks = __VARIANT__;
+export const enableSyncMicroTasks = __VARIANT__;
export const enableNativeEventPriorityInference = __VARIANT__;
diff --git a/packages/shared/forks/ReactFeatureFlags.www.js b/packages/shared/forks/ReactFeatureFlags.www.js
index 5e5cd2105b383..0612eacf80d07 100644
--- a/packages/shared/forks/ReactFeatureFlags.www.js
+++ b/packages/shared/forks/ReactFeatureFlags.www.js
@@ -33,6 +33,7 @@ export const {
disableNativeComponentFrames,
disableSchedulerTimeoutInWorkLoop,
enableDiscreteEventMicroTasks,
+ enableSyncMicroTasks,
enableNativeEventPriorityInference,
} = dynamicFeatureFlags;
diff --git a/scripts/rollup/shims/react-native/ReactNativeViewConfigRegistry.js b/scripts/rollup/shims/react-native/ReactNativeViewConfigRegistry.js
index 2c09ddf3caab1..5f219fea65208 100644
--- a/scripts/rollup/shims/react-native/ReactNativeViewConfigRegistry.js
+++ b/scripts/rollup/shims/react-native/ReactNativeViewConfigRegistry.js
@@ -12,12 +12,8 @@
'use strict';
-import type {
- ReactNativeBaseComponentViewConfig,
- ViewConfigGetter,
-} from './ReactNativeTypes';
-
-const invariant = require('invariant');
+import {type ViewConfig} from './ReactNativeTypes';
+import invariant from 'invariant';
// Event configs
const customBubblingEventTypes: {
@@ -42,9 +38,7 @@ exports.customDirectEventTypes = customDirectEventTypes;
const viewConfigCallbacks = new Map();
const viewConfigs = new Map();
-function processEventTypes(
- viewConfig: ReactNativeBaseComponentViewConfig<>,
-): void {
+function processEventTypes(viewConfig: ViewConfig): void {
const {bubblingEventTypes, directEventTypes} = viewConfig;
if (__DEV__) {
@@ -82,7 +76,7 @@ function processEventTypes(
* A callback is provided to load the view config from UIManager.
* The callback is deferred until the view is actually rendered.
*/
-exports.register = function(name: string, callback: ViewConfigGetter): string {
+exports.register = function(name: string, callback: () => ViewConfig): string {
invariant(
!viewConfigCallbacks.has(name),
'Tried to register two views with the same name %s',
@@ -103,7 +97,7 @@ exports.register = function(name: string, callback: ViewConfigGetter): string {
* If this is the first time the view has been used,
* This configuration will be lazy-loaded from UIManager.
*/
-exports.get = function(name: string): ReactNativeBaseComponentViewConfig<> {
+exports.get = function(name: string): ViewConfig {
let viewConfig;
if (!viewConfigs.has(name)) {
const callback = viewConfigCallbacks.get(name);
diff --git a/scripts/rollup/shims/react-native/createReactNativeComponentClass.js b/scripts/rollup/shims/react-native/createReactNativeComponentClass.js
index 86a758d918b48..f8f4c9284e4c3 100644
--- a/scripts/rollup/shims/react-native/createReactNativeComponentClass.js
+++ b/scripts/rollup/shims/react-native/createReactNativeComponentClass.js
@@ -11,8 +11,7 @@
'use strict';
import {ReactNativeViewConfigRegistry} from 'react-native/Libraries/ReactPrivate/ReactNativePrivateInterface';
-
-import type {ViewConfigGetter} from './ReactNativeTypes';
+import {type ViewConfig} from './ReactNativeTypes';
const {register} = ReactNativeViewConfigRegistry;
@@ -26,7 +25,7 @@ const {register} = ReactNativeViewConfigRegistry;
*/
const createReactNativeComponentClass = function(
name: string,
- callback: ViewConfigGetter,
+ callback: () => ViewConfig,
): string {
return register(name, callback);
};