Skip to content

Commit 63e2343

Browse files
committed
Rename the react.element symbol to react.transitional.element
1 parent bf426f9 commit 63e2343

File tree

10 files changed

+326
-228
lines changed

10 files changed

+326
-228
lines changed

packages/react-devtools-shared/src/__tests__/legacy/inspectElement-test.js

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -290,9 +290,23 @@ describe('InspectedElementContext', () => {
290290
"preview_long": {boolean: true, number: 123, string: "abc"},
291291
},
292292
},
293-
"react_element": Dehydrated {
294-
"preview_short": <span />,
295-
"preview_long": <span />,
293+
"react_element": {
294+
"$$typeof": Dehydrated {
295+
"preview_short": Symbol(react.element),
296+
"preview_long": Symbol(react.element),
297+
},
298+
"_owner": null,
299+
"_store": Dehydrated {
300+
"preview_short": {…},
301+
"preview_long": {},
302+
},
303+
"key": null,
304+
"props": Dehydrated {
305+
"preview_short": {…},
306+
"preview_long": {},
307+
},
308+
"ref": null,
309+
"type": "span",
296310
},
297311
"regexp": Dehydrated {
298312
"preview_short": /abc/giu,

packages/react-devtools-shared/src/backend/ReactSymbols.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,9 @@ export const SERVER_CONTEXT_SYMBOL_STRING = 'Symbol(react.server_context)';
2323

2424
export const DEPRECATED_ASYNC_MODE_SYMBOL_STRING = 'Symbol(react.async_mode)';
2525

26-
export const ELEMENT_NUMBER = 0xeac7;
27-
export const ELEMENT_SYMBOL_STRING = 'Symbol(react.element)';
26+
export const ELEMENT_SYMBOL_STRING = 'Symbol(react.transitional.element)';
27+
export const LEGACY_ELEMENT_NUMBER = 0xeac7;
28+
export const LEGACY_ELEMENT_SYMBOL_STRING = 'Symbol(react.element)';
2829

2930
export const DEBUG_TRACING_MODE_NUMBER = 0xeae1;
3031
export const DEBUG_TRACING_MODE_SYMBOL_STRING =

packages/react-dom/src/__tests__/ReactComponent-test.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -612,6 +612,31 @@ describe('ReactComponent', () => {
612612
);
613613
});
614614

615+
it('throws if a legacy element is used as a child', async () => {
616+
const inlinedElement = {
617+
$$typeof: Symbol.for('react.element'),
618+
type: 'div',
619+
key: null,
620+
ref: null,
621+
props: {},
622+
_owner: null,
623+
};
624+
const element = <div>{[inlinedElement]}</div>;
625+
const container = document.createElement('div');
626+
const root = ReactDOMClient.createRoot(container);
627+
await expect(
628+
act(() => {
629+
root.render(element);
630+
}),
631+
).rejects.toThrowError(
632+
'A React Element from an older version of React was rendered. ' +
633+
'This is not supported. It can happen if:\n' +
634+
'- Multiple copies of the "react" package is used.\n' +
635+
'- A library pre-bundled an old copy of "react" or "react/jsx-runtime".\n' +
636+
'- A compiler tries to "inline" JSX instead of using the runtime.',
637+
);
638+
});
639+
615640
it('throws if a plain object even if it is in an owner', async () => {
616641
class Foo extends React.Component {
617642
render() {

packages/react-dom/src/__tests__/ReactDOMOption-test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ describe('ReactDOMOption', () => {
138138
// This is similar to <fbt>.
139139
// We don't toString it because you must instead provide a value prop.
140140
const obj = {
141-
$$typeof: Symbol.for('react.element'),
141+
$$typeof: Symbol.for('react.transitional.element'),
142142
type: props => props.content,
143143
ref: null,
144144
key: null,

packages/react-dom/src/__tests__/refs-test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -389,7 +389,7 @@ describe('ref swapping', () => {
389389
await expect(async () => {
390390
await act(() => {
391391
root.render({
392-
$$typeof: Symbol.for('react.element'),
392+
$$typeof: Symbol.for('react.transitional.element'),
393393
type: 'div',
394394
props: {
395395
ref: undefined,

packages/react-reconciler/src/ReactChildFiber.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import {
3232
REACT_PORTAL_TYPE,
3333
REACT_LAZY_TYPE,
3434
REACT_CONTEXT_TYPE,
35+
REACT_LEGACY_ELEMENT_TYPE,
3536
} from 'shared/ReactSymbols';
3637
import {
3738
HostRoot,
@@ -166,6 +167,16 @@ function coerceRef(
166167
}
167168

168169
function throwOnInvalidObjectType(returnFiber: Fiber, newChild: Object) {
170+
if (newChild.$$typeof === REACT_LEGACY_ELEMENT_TYPE) {
171+
throw new Error(
172+
'A React Element from an older version of React was rendered. ' +
173+
'This is not supported. It can happen if:\n' +
174+
'- Multiple copies of the "react" package is used.\n' +
175+
'- A library pre-bundled an old copy of "react" or "react/jsx-runtime".\n' +
176+
'- A compiler tries to "inline" JSX instead of using the runtime.',
177+
);
178+
}
179+
169180
// $FlowFixMe[method-unbinding]
170181
const childString = Object.prototype.toString.call(newChild);
171182

packages/react/src/jsx/ReactJSXElement.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ function elementRefGetterWithDeprecationWarning() {
162162
/**
163163
* Factory method to create a new React element. This no longer adheres to
164164
* the class pattern, so do not use new to call it. Also, instanceof check
165-
* will not work. Instead test $$typeof field against Symbol.for('react.element') to check
165+
* will not work. Instead test $$typeof field against Symbol.for('react.transitional.element') to check
166166
* if something is a React Element.
167167
*
168168
* @param {*} type

packages/shared/ReactSymbols.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,10 @@
1212
// Please consider also adding to 'react-devtools-shared/src/backend/ReactSymbols'
1313

1414
// The Symbol used to tag the ReactElement-like types.
15-
export const REACT_ELEMENT_TYPE: symbol = Symbol.for('react.element');
15+
export const REACT_ELEMENT_TYPE: symbol = Symbol.for(
16+
'react.transitional.element',
17+
);
18+
export const REACT_LEGACY_ELEMENT_TYPE: symbol = Symbol.for('react.element');
1619
export const REACT_PORTAL_TYPE: symbol = Symbol.for('react.portal');
1720
export const REACT_FRAGMENT_TYPE: symbol = Symbol.for('react.fragment');
1821
export const REACT_STRICT_MODE_TYPE: symbol = Symbol.for('react.strict_mode');

0 commit comments

Comments
 (0)