Remove _owner field from JSX elements in prod if string refs are disabled (#28739)
In prod, the `_owner` field is only used for string refs so if we have string refs disabled, we don't need this field. In fact, that's one of the big benefits of deprecating them.
Sebastian Markbåge committed
Apr 4, 2024 at 11:20 UTC
fd0da3eef1e23b7dd5071fef21de414da8e5038e
6 files changed
+54
-6
packages/jest-react/src/JestReact.js
+9
-1
@@ -6,7 +6,7 @@
6
*/
7
8
import {REACT_ELEMENT_TYPE, REACT_FRAGMENT_TYPE} from 'shared/ReactSymbols';
9
-import {enableRefAsProp} from 'shared/ReactFeatureFlags';
9
+import {disableStringRefs, enableRefAsProp} from 'shared/ReactFeatureFlags';
10
11
import isArray from 'shared/isArray';
12
@@ -54,6 +54,14 @@ function createJSXElementForTestComparison(type, props) {
54
value: null,
55
});
56
return element;
57
+ } else if (!__DEV__ && disableStringRefs) {
58
+ return {
59
+ $$typeof: REACT_ELEMENT_TYPE,
60
+ type: type,
61
+ key: null,
62
+ ref: null,
63
+ props: props,
64
+ };
65
} else {
66
return {
67
$$typeof: REACT_ELEMENT_TYPE,
packages/react-client/src/ReactFlightClient.js
+11
@@ -38,6 +38,7 @@ import type {Postpone} from 'react/src/ReactPostpone';
38
import type {TemporaryReferenceSet} from './ReactFlightTemporaryReferences';
39
40
import {
41
+ disableStringRefs,
42
enableBinaryFlight,
43
enablePostpone,
44
enableRefAsProp,
@@ -498,6 +499,16 @@ function createElement(
499
enumerable: false,
500
get: nullRefGetter,
501
});
502
+ } else if (!__DEV__ && disableStringRefs) {
503
+ element = ({
504
+ // This tag allows us to uniquely identify this as a React Element
505
+ $$typeof: REACT_ELEMENT_TYPE,
506
+
507
+ type,
508
+ key,
509
+ ref: null,
510
+ props,
511
+ }: any);
512
} else {
513
element = ({
514
// This tag allows us to uniquely identify this as a React Element
packages/react-noop-renderer/src/createReactNoop.js
+13
-1
@@ -32,7 +32,11 @@ import {
32
ConcurrentRoot,
33
LegacyRoot,
34
} from 'react-reconciler/constants';
35
-import {enableRefAsProp, disableLegacyMode} from 'shared/ReactFeatureFlags';
35
+import {
36
+ enableRefAsProp,
37
+ disableLegacyMode,
38
+ disableStringRefs,
39
+} from 'shared/ReactFeatureFlags';
40
41
type Container = {
42
rootID: string,
@@ -799,6 +803,14 @@ function createReactNoop(reconciler: Function, useMutation: boolean) {
803
value: null,
804
});
805
return element;
806
+ } else if (!__DEV__ && disableStringRefs) {
807
+ return {
808
+ $$typeof: REACT_ELEMENT_TYPE,
809
+ type: type,
810
+ key: null,
811
+ ref: null,
812
+ props: props,
813
+ };
814
} else {
815
return {
816
$$typeof: REACT_ELEMENT_TYPE,
packages/react/src/__tests__/ReactCreateElement-test.js
+5
-1
@@ -275,7 +275,11 @@ describe('ReactCreateElement', () => {
275
}
276
const root = ReactDOMClient.createRoot(document.createElement('div'));
277
await act(() => root.render(React.createElement(Wrapper)));
278
- expect(element._owner.stateNode).toBe(instance);
278
+ if (__DEV__ || !gate(flags => flags.disableStringRefs)) {
279
+ expect(element._owner.stateNode).toBe(instance);
280
+ } else {
281
+ expect('_owner' in element).toBe(false);
282
+ }
283
});
284
285
it('merges an additional argument onto the children prop', () => {
packages/react/src/jsx/ReactJSXElement.js
+15
-2
@@ -239,6 +239,19 @@ function ReactElement(type, key, _ref, self, source, owner, props) {
239
value: null,
240
});
241
}
242
+ } else if (!__DEV__ && disableStringRefs) {
243
+ // In prod, `ref` is a regular property and _owner doesn't exist.
244
+ element = {
245
+ // This tag allows us to uniquely identify this as a React Element
246
+ $$typeof: REACT_ELEMENT_TYPE,
247
+
248
+ // Built-in properties that belong on the element
249
+ type,
250
+ key,
251
+ ref,
252
+
253
+ props,
254
+ };
255
} else {
256
// In prod, `ref` is a regular property. It will be removed in a
257
// future release.
@@ -774,7 +787,7 @@ export function cloneAndReplaceKey(oldElement, newKey) {
787
enableRefAsProp ? null : oldElement.ref,
788
undefined,
789
undefined,
777
- oldElement._owner,
790
+ !__DEV__ && disableStringRefs ? undefined : oldElement._owner,
791
oldElement.props,
792
);
793
}
@@ -800,7 +813,7 @@ export function cloneElement(element, config, children) {
813
let ref = enableRefAsProp ? null : element.ref;
814
815
// Owner will be preserved, unless ref is overridden
803
- let owner = element._owner;
816
+ let owner = !__DEV__ && disableStringRefs ? undefined : element._owner;
817
818
if (config != null) {
819
if (hasValidRef(config)) {
packages/shared/ReactElementType.js
+1
-1
@@ -13,7 +13,7 @@ export type ReactElement = {
13
key: any,
14
ref: any,
15
props: any,
16
- // ReactFiber
16
+ // __DEV__ or for string refs
17
_owner: any,
18
19
// __DEV__