diff --git a/packages/react-dom/index.classic.fb.js b/packages/react-dom/index.classic.fb.js index b5e974f2b5f25..33133eafbf316 100644 --- a/packages/react-dom/index.classic.fb.js +++ b/packages/react-dom/index.classic.fb.js @@ -20,11 +20,8 @@ Object.assign((Internals: any), { export { createPortal, - createRoot, - hydrateRoot, findDOMNode, flushSync, - render, unmountComponentAtNode, unstable_batchedUpdates, unstable_createEventHandle, @@ -41,4 +38,6 @@ export { version, } from './src/client/ReactDOM'; +export {createRoot, hydrateRoot, render} from './src/client/ReactDOMRootFB'; + export {Internals as __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED}; diff --git a/packages/react-dom/index.modern.fb.js b/packages/react-dom/index.modern.fb.js index 531f4d429b611..0bff591fac7c9 100644 --- a/packages/react-dom/index.modern.fb.js +++ b/packages/react-dom/index.modern.fb.js @@ -10,8 +10,6 @@ export {default as __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED} from './src/ReactDOMSharedInternals'; export { createPortal, - createRoot, - hydrateRoot, flushSync, unstable_batchedUpdates, unstable_createEventHandle, @@ -26,3 +24,5 @@ export { preinitModule, version, } from './src/client/ReactDOM'; + +export {createRoot, hydrateRoot} from './src/client/ReactDOMRootFB'; diff --git a/packages/react-dom/src/__tests__/ReactDOMServerPartialHydration-test.internal.js b/packages/react-dom/src/__tests__/ReactDOMServerPartialHydration-test.internal.js index ea43fc2c16dfc..b706f5f6a6472 100644 --- a/packages/react-dom/src/__tests__/ReactDOMServerPartialHydration-test.internal.js +++ b/packages/react-dom/src/__tests__/ReactDOMServerPartialHydration-test.internal.js @@ -331,7 +331,7 @@ describe('ReactDOMServerPartialHydration', () => { 'Component', 'Component', // Hydration mismatch is logged - 'Hydration failed because the server rendered HTML didn\'t match the client.', + "Hydration failed because the server rendered HTML didn't match the client.", 'There was an error while hydrating this Suspense boundary.', ]); @@ -1162,7 +1162,7 @@ describe('ReactDOMServerPartialHydration', () => { }); assertLog([ - 'Hydration failed because the server rendered HTML didn\'t match the client.', + "Hydration failed because the server rendered HTML didn't match the client.", 'There was an error while hydrating this Suspense boundary.', ]); diff --git a/packages/react-dom/src/client/ReactDOMRootFB.js b/packages/react-dom/src/client/ReactDOMRootFB.js new file mode 100644 index 0000000000000..ac48d1f152563 --- /dev/null +++ b/packages/react-dom/src/client/ReactDOMRootFB.js @@ -0,0 +1,418 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow + */ + +import type {ReactNodeList} from 'shared/ReactTypes'; + +import type { + RootType, + CreateRootOptions, + HydrateRootOptions, +} from './ReactDOMRoot'; + +import type {FiberRoot} from 'react-reconciler/src/ReactInternalTypes'; + +import type { + Container, + PublicInstance, +} from 'react-dom-bindings/src/client/ReactFiberConfigDOM'; + +import { + createRoot as createRootImpl, + hydrateRoot as hydrateRootImpl, +} from './ReactDOMRoot'; + +import {disableLegacyMode} from 'shared/ReactFeatureFlags'; +import {clearContainer} from 'react-dom-bindings/src/client/ReactFiberConfigDOM'; +import { + getInstanceFromNode, + isContainerMarkedAsRoot, + markContainerAsRoot, +} from 'react-dom-bindings/src/client/ReactDOMComponentTree'; +import {listenToAllSupportedEvents} from 'react-dom-bindings/src/events/DOMPluginEventSystem'; +import {isValidContainerLegacy} from './ReactDOMRoot'; +import { + DOCUMENT_NODE, + COMMENT_NODE, +} from 'react-dom-bindings/src/client/HTMLNodeType'; + +import { + createContainer, + createHydrationContainer, + findHostInstanceWithNoPortals, + updateContainer, + flushSync, + getPublicRootInstance, + defaultOnUncaughtError, + defaultOnCaughtError, +} from 'react-reconciler/src/ReactFiberReconciler'; +import {LegacyRoot} from 'react-reconciler/src/ReactRootTags'; +import {has as hasInstance} from 'shared/ReactInstanceMap'; + +import assign from 'shared/assign'; + +// Provided by www +const ReactFiberErrorDialogWWW = require('ReactFiberErrorDialog'); + +if (typeof ReactFiberErrorDialogWWW.showErrorDialog !== 'function') { + throw new Error( + 'Expected ReactFiberErrorDialog.showErrorDialog to be a function.', + ); +} + +function wwwOnUncaughtError( + error: mixed, + errorInfo: {+componentStack?: ?string}, +): void { + const componentStack = + errorInfo.componentStack != null ? errorInfo.componentStack : ''; + const logError = ReactFiberErrorDialogWWW.showErrorDialog({ + errorBoundary: null, + error, + componentStack, + }); + + // Allow injected showErrorDialog() to prevent default console.error logging. + // This enables renderers like ReactNative to better manage redbox behavior. + if (logError === false) { + return; + } + + defaultOnUncaughtError(error, errorInfo); +} + +function wwwOnCaughtError( + error: mixed, + errorInfo: { + +componentStack?: ?string, + +errorBoundary?: ?React$Component, + }, +): void { + const errorBoundary = errorInfo.errorBoundary; + const componentStack = + errorInfo.componentStack != null ? errorInfo.componentStack : ''; + const logError = ReactFiberErrorDialogWWW.showErrorDialog({ + errorBoundary, + error, + componentStack, + }); + + // Allow injected showErrorDialog() to prevent default console.error logging. + // This enables renderers like ReactNative to better manage redbox behavior. + if (logError === false) { + return; + } + + defaultOnCaughtError(error, errorInfo); +} + +export function createRoot( + container: Element | Document | DocumentFragment, + options?: CreateRootOptions, +): RootType { + return createRootImpl( + container, + assign( + ({ + onUncaughtError: wwwOnUncaughtError, + onCaughtError: wwwOnCaughtError, + }: any), + options, + ), + ); +} + +export function hydrateRoot( + container: Document | Element, + initialChildren: ReactNodeList, + options?: HydrateRootOptions, +): RootType { + return hydrateRootImpl( + container, + initialChildren, + assign( + ({ + onUncaughtError: wwwOnUncaughtError, + onCaughtError: wwwOnCaughtError, + }: any), + options, + ), + ); +} + +let topLevelUpdateWarnings; + +if (__DEV__) { + topLevelUpdateWarnings = (container: Container) => { + if (container._reactRootContainer && container.nodeType !== COMMENT_NODE) { + const hostInstance = findHostInstanceWithNoPortals( + container._reactRootContainer.current, + ); + if (hostInstance) { + if (hostInstance.parentNode !== container) { + console.error( + 'It looks like the React-rendered content of this ' + + 'container was removed without using React. This is not ' + + 'supported and will cause errors. Instead, call ' + + 'ReactDOM.unmountComponentAtNode to empty a container.', + ); + } + } + } + + const isRootRenderedBySomeReact = !!container._reactRootContainer; + const rootEl = getReactRootElementInContainer(container); + const hasNonRootReactChild = !!(rootEl && getInstanceFromNode(rootEl)); + + if (hasNonRootReactChild && !isRootRenderedBySomeReact) { + console.error( + 'Replacing React-rendered children with a new root ' + + 'component. If you intended to update the children of this node, ' + + 'you should instead have the existing children update their state ' + + 'and render the new components instead of calling ReactDOM.render.', + ); + } + }; +} + +function getReactRootElementInContainer(container: any) { + if (!container) { + return null; + } + + if (container.nodeType === DOCUMENT_NODE) { + return container.documentElement; + } else { + return container.firstChild; + } +} + +function noopOnRecoverableError() { + // This isn't reachable because onRecoverableError isn't called in the + // legacy API. +} + +function legacyCreateRootFromDOMContainer( + container: Container, + initialChildren: ReactNodeList, + parentComponent: ?React$Component, + callback: ?Function, + isHydrationContainer: boolean, +): FiberRoot { + if (isHydrationContainer) { + if (typeof callback === 'function') { + const originalCallback = callback; + callback = function () { + const instance = getPublicRootInstance(root); + originalCallback.call(instance); + }; + } + + const root: FiberRoot = createHydrationContainer( + initialChildren, + callback, + container, + LegacyRoot, + null, // hydrationCallbacks + false, // isStrictMode + false, // concurrentUpdatesByDefaultOverride, + '', // identifierPrefix + wwwOnUncaughtError, + wwwOnCaughtError, + noopOnRecoverableError, + // TODO(luna) Support hydration later + null, + null, + ); + container._reactRootContainer = root; + markContainerAsRoot(root.current, container); + + const rootContainerElement = + container.nodeType === COMMENT_NODE ? container.parentNode : container; + // $FlowFixMe[incompatible-call] + listenToAllSupportedEvents(rootContainerElement); + + flushSync(); + return root; + } else { + // First clear any existing content. + clearContainer(container); + + if (typeof callback === 'function') { + const originalCallback = callback; + callback = function () { + const instance = getPublicRootInstance(root); + originalCallback.call(instance); + }; + } + + const root = createContainer( + container, + LegacyRoot, + null, // hydrationCallbacks + false, // isStrictMode + false, // concurrentUpdatesByDefaultOverride, + '', // identifierPrefix + wwwOnUncaughtError, + wwwOnCaughtError, + noopOnRecoverableError, + null, // transitionCallbacks + ); + container._reactRootContainer = root; + markContainerAsRoot(root.current, container); + + const rootContainerElement = + container.nodeType === COMMENT_NODE ? container.parentNode : container; + // $FlowFixMe[incompatible-call] + listenToAllSupportedEvents(rootContainerElement); + + // Initial mount should not be batched. + flushSync(() => { + updateContainer(initialChildren, root, parentComponent, callback); + }); + + return root; + } +} + +function warnOnInvalidCallback(callback: mixed): void { + if (__DEV__) { + if (callback !== null && typeof callback !== 'function') { + console.error( + 'Expected the last optional `callback` argument to be a ' + + 'function. Instead received: %s.', + callback, + ); + } + } +} + +function legacyRenderSubtreeIntoContainer( + parentComponent: ?React$Component, + children: ReactNodeList, + container: Container, + forceHydrate: boolean, + callback: ?Function, +): React$Component | PublicInstance | null { + if (__DEV__) { + topLevelUpdateWarnings(container); + warnOnInvalidCallback(callback === undefined ? null : callback); + } + + const maybeRoot = container._reactRootContainer; + let root: FiberRoot; + if (!maybeRoot) { + // Initial mount + root = legacyCreateRootFromDOMContainer( + container, + children, + parentComponent, + callback, + forceHydrate, + ); + } else { + root = maybeRoot; + if (typeof callback === 'function') { + const originalCallback = callback; + callback = function () { + const instance = getPublicRootInstance(root); + originalCallback.call(instance); + }; + } + // Update + updateContainer(children, root, parentComponent, callback); + } + return getPublicRootInstance(root); +} + +export function render( + element: React$Element, + container: Container, + callback: ?Function, +): React$Component | PublicInstance | null { + if (disableLegacyMode) { + if (__DEV__) { + console.error( + 'ReactDOM.render is no longer supported in React 18. Use createRoot instead.', + ); + } + throw new Error('ReactDOM: Unsupported Legacy Mode API.'); + } + if (__DEV__) { + console.error( + 'ReactDOM.render is no longer supported in React 18. Use createRoot ' + + 'instead. Until you switch to the new API, your app will behave as ' + + "if it's running React 17. Learn " + + 'more: https://react.dev/link/switch-to-createroot', + ); + } + + if (!isValidContainerLegacy(container)) { + throw new Error('Target container is not a DOM element.'); + } + + if (__DEV__) { + const isModernRoot = + isContainerMarkedAsRoot(container) && + container._reactRootContainer === undefined; + if (isModernRoot) { + console.error( + 'You are calling ReactDOM.render() on a container that was previously ' + + 'passed to ReactDOMClient.createRoot(). This is not supported. ' + + 'Did you mean to call root.render(element)?', + ); + } + } + return legacyRenderSubtreeIntoContainer( + null, + element, + container, + false, + callback, + ); +} + +export function unstable_renderSubtreeIntoContainer( + parentComponent: React$Component, + element: React$Element, + containerNode: Container, + callback: ?Function, +): React$Component | PublicInstance | null { + if (disableLegacyMode) { + if (__DEV__) { + console.error( + 'ReactDOM.unstable_renderSubtreeIntoContainer() is no longer supported in React 18. Consider using a portal instead.', + ); + } + throw new Error('ReactDOM: Unsupported Legacy Mode API.'); + } + if (__DEV__) { + console.error( + 'ReactDOM.unstable_renderSubtreeIntoContainer() is no longer supported ' + + 'in React 18. Consider using a portal instead. Until you switch to ' + + "the createRoot API, your app will behave as if it's running React " + + '17. Learn more: https://react.dev/link/switch-to-createroot', + ); + } + + if (!isValidContainerLegacy(containerNode)) { + throw new Error('Target container is not a DOM element.'); + } + + if (parentComponent == null || !hasInstance(parentComponent)) { + throw new Error('parentComponent must be a valid React Component'); + } + + return legacyRenderSubtreeIntoContainer( + parentComponent, + element, + containerNode, + false, + callback, + ); +} diff --git a/packages/react-native-renderer/src/ReactFabric.js b/packages/react-native-renderer/src/ReactFabric.js index 0917cf4360d00..6cdb179093b12 100644 --- a/packages/react-native-renderer/src/ReactFabric.js +++ b/packages/react-native-renderer/src/ReactFabric.js @@ -46,6 +46,60 @@ import { } from './ReactNativePublicCompat'; import {getPublicInstanceFromInternalInstanceHandle} from './ReactFiberConfigFabric'; +// Module provided by RN: +import {ReactFiberErrorDialog} from 'react-native/Libraries/ReactPrivate/ReactNativePrivateInterface'; + +if (typeof ReactFiberErrorDialog.showErrorDialog !== 'function') { + throw new Error( + 'Expected ReactFiberErrorDialog.showErrorDialog to be a function.', + ); +} + +function nativeOnUncaughtError( + error: mixed, + errorInfo: {+componentStack?: ?string}, +): void { + const componentStack = + errorInfo.componentStack != null ? errorInfo.componentStack : ''; + const logError = ReactFiberErrorDialog.showErrorDialog({ + errorBoundary: null, + error, + componentStack, + }); + + // Allow injected showErrorDialog() to prevent default console.error logging. + // This enables renderers like ReactNative to better manage redbox behavior. + if (logError === false) { + return; + } + + defaultOnUncaughtError(error, errorInfo); +} +function nativeOnCaughtError( + error: mixed, + errorInfo: { + +componentStack?: ?string, + +errorBoundary?: ?React$Component, + }, +): void { + const errorBoundary = errorInfo.errorBoundary; + const componentStack = + errorInfo.componentStack != null ? errorInfo.componentStack : ''; + const logError = ReactFiberErrorDialog.showErrorDialog({ + errorBoundary, + error, + componentStack, + }); + + // Allow injected showErrorDialog() to prevent default console.error logging. + // This enables renderers like ReactNative to better manage redbox behavior. + if (logError === false) { + return; + } + + defaultOnCaughtError(error, errorInfo); +} + function render( element: Element, containerTag: number, @@ -64,8 +118,8 @@ function render( false, null, '', - defaultOnUncaughtError, - defaultOnCaughtError, + nativeOnUncaughtError, + nativeOnCaughtError, defaultOnRecoverableError, null, ); diff --git a/packages/react-native-renderer/src/ReactNativeRenderer.js b/packages/react-native-renderer/src/ReactNativeRenderer.js index 197fe1b91b439..5409eb3df4f98 100644 --- a/packages/react-native-renderer/src/ReactNativeRenderer.js +++ b/packages/react-native-renderer/src/ReactNativeRenderer.js @@ -50,6 +50,60 @@ import { isChildPublicInstance, } from './ReactNativePublicCompat'; +// Module provided by RN: +import {ReactFiberErrorDialog} from 'react-native/Libraries/ReactPrivate/ReactNativePrivateInterface'; + +if (typeof ReactFiberErrorDialog.showErrorDialog !== 'function') { + throw new Error( + 'Expected ReactFiberErrorDialog.showErrorDialog to be a function.', + ); +} + +function nativeOnUncaughtError( + error: mixed, + errorInfo: {+componentStack?: ?string}, +): void { + const componentStack = + errorInfo.componentStack != null ? errorInfo.componentStack : ''; + const logError = ReactFiberErrorDialog.showErrorDialog({ + errorBoundary: null, + error, + componentStack, + }); + + // Allow injected showErrorDialog() to prevent default console.error logging. + // This enables renderers like ReactNative to better manage redbox behavior. + if (logError === false) { + return; + } + + defaultOnUncaughtError(error, errorInfo); +} +function nativeOnCaughtError( + error: mixed, + errorInfo: { + +componentStack?: ?string, + +errorBoundary?: ?React$Component, + }, +): void { + const errorBoundary = errorInfo.errorBoundary; + const componentStack = + errorInfo.componentStack != null ? errorInfo.componentStack : ''; + const logError = ReactFiberErrorDialog.showErrorDialog({ + errorBoundary, + error, + componentStack, + }); + + // Allow injected showErrorDialog() to prevent default console.error logging. + // This enables renderers like ReactNative to better manage redbox behavior. + if (logError === false) { + return; + } + + defaultOnCaughtError(error, errorInfo); +} + function render( element: Element, containerTag: number, @@ -67,8 +121,8 @@ function render( false, null, '', - defaultOnUncaughtError, - defaultOnCaughtError, + nativeOnUncaughtError, + nativeOnCaughtError, defaultOnRecoverableError, null, ); diff --git a/packages/react-reconciler/src/ReactFiberErrorDialog.js b/packages/react-reconciler/src/ReactFiberErrorDialog.js deleted file mode 100644 index 4e415ee6ddb79..0000000000000 --- a/packages/react-reconciler/src/ReactFiberErrorDialog.js +++ /dev/null @@ -1,20 +0,0 @@ -/** - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - * @flow - */ - -// This module is forked in different environments. -// By default, return `true` to log errors to the console. -// Forks can return `false` if this isn't desirable. - -export function showErrorDialog( - errorBoundary: ?React$Component, - error: mixed, - componentStack: string, -): boolean { - return true; -} diff --git a/packages/react-reconciler/src/ReactFiberErrorLogger.js b/packages/react-reconciler/src/ReactFiberErrorLogger.js index 0ab443a964ac0..775ca9b20aa92 100644 --- a/packages/react-reconciler/src/ReactFiberErrorLogger.js +++ b/packages/react-reconciler/src/ReactFiberErrorLogger.js @@ -10,7 +10,6 @@ import type {Fiber, FiberRoot} from './ReactInternalTypes'; import type {CapturedValue} from './ReactCapturedValue'; -import {showErrorDialog} from './ReactFiberErrorDialog'; import getComponentNameFromFiber from 'react-reconciler/src/getComponentNameFromFiber'; import {ClassComponent} from './ReactWorkTags'; @@ -28,23 +27,16 @@ export function defaultOnUncaughtError( error: mixed, errorInfo: {+componentStack?: ?string}, ): void { - const componentStack = - errorInfo.componentStack != null ? errorInfo.componentStack : ''; - const logError = showErrorDialog(null, error, componentStack); - - // Allow injected showErrorDialog() to prevent default console.error logging. - // This enables renderers like ReactNative to better manage redbox behavior. - if (logError === false) { - return; - } + // Overriding this can silence these warnings e.g. for tests. + // See https://github.com/facebook/react/pull/13384 // For uncaught root errors we report them as uncaught to the browser's // onerror callback. This won't have component stacks and the error addendum. // So we add those into a separate console.warn. reportGlobalError(error); if (__DEV__) { - // TODO: There's no longer a way to silence these warnings e.g. for tests. - // See https://github.com/facebook/react/pull/13384 + const componentStack = + errorInfo.componentStack != null ? errorInfo.componentStack : ''; const componentNameMessage = componentName ? `An error occurred in the <${componentName}> component:` @@ -70,19 +62,11 @@ export function defaultOnCaughtError( // Overriding this can silence these warnings e.g. for tests. // See https://github.com/facebook/react/pull/13384 - const boundary = errorInfo.errorBoundary; - const componentStack = - errorInfo.componentStack != null ? errorInfo.componentStack : ''; - const logError = showErrorDialog(boundary, error, componentStack); - - // Allow injected showErrorDialog() to prevent default console.error logging. - // This enables renderers like ReactNative to better manage redbox behavior. - if (logError === false) { - return; - } - // Caught by error boundary if (__DEV__) { + const componentStack = + errorInfo.componentStack != null ? errorInfo.componentStack : ''; + const componentNameMessage = componentName ? `The above error occurred in the <${componentName}> component:` : 'The above error occurred in one of your React components:'; diff --git a/packages/react-reconciler/src/forks/ReactFiberErrorDialog.native.js b/packages/react-reconciler/src/forks/ReactFiberErrorDialog.native.js deleted file mode 100644 index 1f5a34f6bc179..0000000000000 --- a/packages/react-reconciler/src/forks/ReactFiberErrorDialog.native.js +++ /dev/null @@ -1,29 +0,0 @@ -/** - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - * @flow - */ - -// Module provided by RN: -import {ReactFiberErrorDialog as RNImpl} from 'react-native/Libraries/ReactPrivate/ReactNativePrivateInterface'; - -if (typeof RNImpl.showErrorDialog !== 'function') { - throw new Error( - 'Expected ReactFiberErrorDialog.showErrorDialog to be a function.', - ); -} - -export function showErrorDialog( - errorBoundary: ?React$Component, - error: mixed, - componentStack: string, -): boolean { - return RNImpl.showErrorDialog({ - componentStack, - error, - errorBoundary, - }); -} diff --git a/packages/react-reconciler/src/forks/ReactFiberErrorDialog.www.js b/packages/react-reconciler/src/forks/ReactFiberErrorDialog.www.js deleted file mode 100644 index e2e0a4943aa44..0000000000000 --- a/packages/react-reconciler/src/forks/ReactFiberErrorDialog.www.js +++ /dev/null @@ -1,29 +0,0 @@ -/** - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - * @flow - */ - -// Provided by www -const ReactFiberErrorDialogWWW = require('ReactFiberErrorDialog'); - -if (typeof ReactFiberErrorDialogWWW.showErrorDialog !== 'function') { - throw new Error( - 'Expected ReactFiberErrorDialog.showErrorDialog to be a function.', - ); -} - -export function showErrorDialog( - errorBoundary: ?React$Component, - error: mixed, - componentStack: string, -): boolean { - return ReactFiberErrorDialogWWW.showErrorDialog({ - errorBoundary, - error, - componentStack, - }); -} diff --git a/scripts/rollup/forks.js b/scripts/rollup/forks.js index eef64866e1932..f1ed750c22d60 100644 --- a/scripts/rollup/forks.js +++ b/scripts/rollup/forks.js @@ -232,36 +232,6 @@ const forks = Object.freeze({ } }, - // Different dialogs for caught errors. - './packages/react-reconciler/src/ReactFiberErrorDialog.js': ( - bundleType, - entry - ) => { - switch (bundleType) { - case FB_WWW_DEV: - case FB_WWW_PROD: - case FB_WWW_PROFILING: - // Use the www fork which shows an error dialog. - return './packages/react-reconciler/src/forks/ReactFiberErrorDialog.www.js'; - case RN_OSS_DEV: - case RN_OSS_PROD: - case RN_OSS_PROFILING: - case RN_FB_DEV: - case RN_FB_PROD: - case RN_FB_PROFILING: - switch (entry) { - case 'react-native-renderer': - case 'react-native-renderer/fabric': - // Use the RN fork which plays well with redbox. - return './packages/react-reconciler/src/forks/ReactFiberErrorDialog.native.js'; - default: - return null; - } - default: - return null; - } - }, - './packages/react-reconciler/src/ReactFiberConfig.js': ( bundleType, entry,