Skip to content

Commit fd0da3e

Browse files
authored
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.
1 parent 48b4ecc commit fd0da3e

File tree

6 files changed

+54
-6
lines changed

6 files changed

+54
-6
lines changed

packages/jest-react/src/JestReact.js

+9-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
*/
77

88
import {REACT_ELEMENT_TYPE, REACT_FRAGMENT_TYPE} from 'shared/ReactSymbols';
9-
import {enableRefAsProp} from 'shared/ReactFeatureFlags';
9+
import {disableStringRefs, enableRefAsProp} from 'shared/ReactFeatureFlags';
1010

1111
import isArray from 'shared/isArray';
1212

@@ -54,6 +54,14 @@ function createJSXElementForTestComparison(type, props) {
5454
value: null,
5555
});
5656
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+
};
5765
} else {
5866
return {
5967
$$typeof: REACT_ELEMENT_TYPE,

packages/react-client/src/ReactFlightClient.js

+11
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ import type {Postpone} from 'react/src/ReactPostpone';
3838
import type {TemporaryReferenceSet} from './ReactFlightTemporaryReferences';
3939

4040
import {
41+
disableStringRefs,
4142
enableBinaryFlight,
4243
enablePostpone,
4344
enableRefAsProp,
@@ -498,6 +499,16 @@ function createElement(
498499
enumerable: false,
499500
get: nullRefGetter,
500501
});
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);
501512
} else {
502513
element = ({
503514
// This tag allows us to uniquely identify this as a React Element

packages/react-noop-renderer/src/createReactNoop.js

+13-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,11 @@ import {
3232
ConcurrentRoot,
3333
LegacyRoot,
3434
} from 'react-reconciler/constants';
35-
import {enableRefAsProp, disableLegacyMode} from 'shared/ReactFeatureFlags';
35+
import {
36+
enableRefAsProp,
37+
disableLegacyMode,
38+
disableStringRefs,
39+
} from 'shared/ReactFeatureFlags';
3640

3741
type Container = {
3842
rootID: string,
@@ -799,6 +803,14 @@ function createReactNoop(reconciler: Function, useMutation: boolean) {
799803
value: null,
800804
});
801805
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+
};
802814
} else {
803815
return {
804816
$$typeof: REACT_ELEMENT_TYPE,

packages/react/src/__tests__/ReactCreateElement-test.js

+5-1
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,11 @@ describe('ReactCreateElement', () => {
275275
}
276276
const root = ReactDOMClient.createRoot(document.createElement('div'));
277277
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+
}
279283
});
280284

281285
it('merges an additional argument onto the children prop', () => {

packages/react/src/jsx/ReactJSXElement.js

+15-2
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,19 @@ function ReactElement(type, key, _ref, self, source, owner, props) {
239239
value: null,
240240
});
241241
}
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+
};
242255
} else {
243256
// In prod, `ref` is a regular property. It will be removed in a
244257
// future release.
@@ -774,7 +787,7 @@ export function cloneAndReplaceKey(oldElement, newKey) {
774787
enableRefAsProp ? null : oldElement.ref,
775788
undefined,
776789
undefined,
777-
oldElement._owner,
790+
!__DEV__ && disableStringRefs ? undefined : oldElement._owner,
778791
oldElement.props,
779792
);
780793
}
@@ -800,7 +813,7 @@ export function cloneElement(element, config, children) {
800813
let ref = enableRefAsProp ? null : element.ref;
801814

802815
// Owner will be preserved, unless ref is overridden
803-
let owner = element._owner;
816+
let owner = !__DEV__ && disableStringRefs ? undefined : element._owner;
804817

805818
if (config != null) {
806819
if (hasValidRef(config)) {

packages/shared/ReactElementType.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ export type ReactElement = {
1313
key: any,
1414
ref: any,
1515
props: any,
16-
// ReactFiber
16+
// __DEV__ or for string refs
1717
_owner: any,
1818

1919
// __DEV__

0 commit comments

Comments
 (0)