diff --git a/packages/react-native-renderer/src/ReactNativeRenderer.js b/packages/react-native-renderer/src/ReactNativeRenderer.js index 528c8abe91800..5c2957aed16e5 100644 --- a/packages/react-native-renderer/src/ReactNativeRenderer.js +++ b/packages/react-native-renderer/src/ReactNativeRenderer.js @@ -56,6 +56,20 @@ import {disableLegacyMode} from 'shared/ReactFeatureFlags'; // Module provided by RN: import {ReactFiberErrorDialog} from 'react-native/Libraries/ReactPrivate/ReactNativePrivateInterface'; +import reactNativePackageVersion from 'shared/ReactVersion'; +import * as IsomorphicReactPackage from 'react'; + +const isomorphicReactPackageVersion = IsomorphicReactPackage.version; +if (isomorphicReactPackageVersion !== reactNativePackageVersion) { + throw new Error( + 'Incompatible React versions: The "react" and "react-native-renderer" packages must ' + + 'have the exact same version. Instead got:\n' + + ` - react: ${isomorphicReactPackageVersion}\n` + + ` - react-native-renderer: ${reactNativePackageVersion}\n` + + 'Learn more: https://react.dev/warnings/version-mismatch', + ); +} + if (typeof ReactFiberErrorDialog.showErrorDialog !== 'function') { throw new Error( 'Expected ReactFiberErrorDialog.showErrorDialog to be a function.', diff --git a/packages/react/src/__tests__/ReactMismatchedVersions-test.js b/packages/react/src/__tests__/ReactMismatchedVersions-test.js index f578fb766a523..cee86e5087d6b 100644 --- a/packages/react/src/__tests__/ReactMismatchedVersions-test.js +++ b/packages/react/src/__tests__/ReactMismatchedVersions-test.js @@ -15,16 +15,22 @@ describe('ReactMismatchedVersions-test', () => { require('web-streams-polyfill/ponyfill/es6').ReadableStream; global.TextEncoder = require('util').TextEncoder; - jest.mock('react', () => { - const actualReact = jest.requireActual('react'); - return { - ...actualReact, - version: '18.0.0-whoa-this-aint-the-right-react', - __actualVersion: actualReact.version, - }; + let React; + let actualReactVersion; + + beforeEach(() => { + jest.resetModules(); + jest.mock('react', () => { + const actualReact = jest.requireActual('react'); + return { + ...actualReact, + version: '18.0.0-whoa-this-aint-the-right-react', + __actualVersion: actualReact.version, + }; + }); + React = require('react'); + actualReactVersion = React.__actualVersion; }); - const React = require('react'); - const actualReactVersion = React.__actualVersion; test('importing "react-dom/client" throws if version does not match React version', async () => { expect(() => require('react-dom/client')).toThrow( @@ -124,4 +130,14 @@ describe('ReactMismatchedVersions-test', () => { ` - react-dom: ${actualReactVersion}`, ); }); + + // @gate source + test('importing "react-native-renderer" throws if version does not match React version', async () => { + expect(() => require('react-native-renderer')).toThrow( + 'Incompatible React versions: The "react" and "react-native-renderer" packages ' + + 'must have the exact same version. Instead got:\n' + + ' - react: 18.0.0-whoa-this-aint-the-right-react\n' + + ` - react-native-renderer: ${actualReactVersion}`, + ); + }); });