Skip to content

Commit 681a4aa

Browse files
authored
Throw if React and React DOM versions don't match (#29236)
Throw an error during module initialization if the version of the "react-dom" package does not match the version of "react". We used to be more relaxed about this, because the "react" package changed so infrequently. However, we now have many more features that rely on an internal protocol between the two packages, including Hooks, Float, and the compiler runtime. So it's important that both packages are versioned in lockstep. Before this change, a version mismatch would often result in a cryptic internal error with no indication of the root cause. Instead, we will now compare the versions during module initialization and immediately throw an error to catch mistakes as early as possible and provide a clear error message.
1 parent 4ec6a6f commit 681a4aa

14 files changed

+217
-1
lines changed

packages/react-dom/src/client/ReactDOMClient.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ import ReactVersion from 'shared/ReactVersion';
1919
import {getClosestInstanceFromNode} from 'react-dom-bindings/src/client/ReactDOMComponentTree';
2020
import Internals from 'shared/ReactDOMSharedInternals';
2121

22+
import {ensureCorrectIsomorphicReactVersion} from '../shared/ensureCorrectIsomorphicReactVersion';
23+
ensureCorrectIsomorphicReactVersion();
24+
2225
if (__DEV__) {
2326
if (
2427
typeof Map !== 'function' ||

packages/react-dom/src/client/ReactDOMClientFB.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ import {createPortal as createPortalImpl} from 'react-reconciler/src/ReactPortal
2525
import {canUseDOM} from 'shared/ExecutionEnvironment';
2626
import ReactVersion from 'shared/ReactVersion';
2727

28+
import {ensureCorrectIsomorphicReactVersion} from '../shared/ensureCorrectIsomorphicReactVersion';
29+
ensureCorrectIsomorphicReactVersion();
30+
2831
import {
2932
getClosestInstanceFromNode,
3033
getInstanceFromNode,

packages/react-dom/src/server/ReactDOMFizzServerBrowser.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ import {
3737
createRootFormatContext,
3838
} from 'react-dom-bindings/src/server/ReactFizzConfigDOM';
3939

40+
import {ensureCorrectIsomorphicReactVersion} from '../shared/ensureCorrectIsomorphicReactVersion';
41+
ensureCorrectIsomorphicReactVersion();
42+
4043
type Options = {
4144
identifierPrefix?: string,
4245
namespaceURI?: string,

packages/react-dom/src/server/ReactDOMFizzServerBun.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ import {
3131
createRootFormatContext,
3232
} from 'react-dom-bindings/src/server/ReactFizzConfigDOM';
3333

34+
import {ensureCorrectIsomorphicReactVersion} from '../shared/ensureCorrectIsomorphicReactVersion';
35+
ensureCorrectIsomorphicReactVersion();
36+
3437
type Options = {
3538
identifierPrefix?: string,
3639
namespaceURI?: string,

packages/react-dom/src/server/ReactDOMFizzServerEdge.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ import {
3737
createRootFormatContext,
3838
} from 'react-dom-bindings/src/server/ReactFizzConfigDOM';
3939

40+
import {ensureCorrectIsomorphicReactVersion} from '../shared/ensureCorrectIsomorphicReactVersion';
41+
ensureCorrectIsomorphicReactVersion();
42+
4043
type Options = {
4144
identifierPrefix?: string,
4245
namespaceURI?: string,

packages/react-dom/src/server/ReactDOMFizzServerNode.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@ import {
4141
createRootFormatContext,
4242
} from 'react-dom-bindings/src/server/ReactFizzConfigDOM';
4343

44+
import {ensureCorrectIsomorphicReactVersion} from '../shared/ensureCorrectIsomorphicReactVersion';
45+
ensureCorrectIsomorphicReactVersion();
46+
4447
function createDrainHandler(destination: Destination, request: Request) {
4548
return () => startFlowing(request, destination);
4649
}

packages/react-dom/src/server/ReactDOMFizzStaticBrowser.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ import {
3636
createRootFormatContext,
3737
} from 'react-dom-bindings/src/server/ReactFizzConfigDOM';
3838

39+
import {ensureCorrectIsomorphicReactVersion} from '../shared/ensureCorrectIsomorphicReactVersion';
40+
ensureCorrectIsomorphicReactVersion();
41+
3942
type Options = {
4043
identifierPrefix?: string,
4144
namespaceURI?: string,

packages/react-dom/src/server/ReactDOMFizzStaticEdge.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ import {
3636
createRootFormatContext,
3737
} from 'react-dom-bindings/src/server/ReactFizzConfigDOM';
3838

39+
import {ensureCorrectIsomorphicReactVersion} from '../shared/ensureCorrectIsomorphicReactVersion';
40+
ensureCorrectIsomorphicReactVersion();
41+
3942
type Options = {
4043
identifierPrefix?: string,
4144
namespaceURI?: string,

packages/react-dom/src/server/ReactDOMFizzStaticNode.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ import {
3737
createRootFormatContext,
3838
} from 'react-dom-bindings/src/server/ReactFizzConfigDOM';
3939

40+
import {ensureCorrectIsomorphicReactVersion} from '../shared/ensureCorrectIsomorphicReactVersion';
41+
ensureCorrectIsomorphicReactVersion();
42+
4043
type Options = {
4144
identifierPrefix?: string,
4245
namespaceURI?: string,
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/**
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*
7+
* @flow
8+
*/
9+
10+
import reactDOMPackageVersion from 'shared/ReactVersion';
11+
import * as IsomorphicReactPackage from 'react';
12+
13+
export function ensureCorrectIsomorphicReactVersion() {
14+
const isomorphicReactPackageVersion = IsomorphicReactPackage.version;
15+
if (isomorphicReactPackageVersion !== reactDOMPackageVersion) {
16+
throw new Error(
17+
'Incompatible React versions: The "react" and "react-dom" packages must ' +
18+
'have the exact same version. Instead got:\n' +
19+
` - react: ${isomorphicReactPackageVersion}\n` +
20+
` - react-dom: ${reactDOMPackageVersion}\n` +
21+
'Learn more: https://react.dev/warnings/version-mismatch',
22+
);
23+
}
24+
}

0 commit comments

Comments
 (0)