@samitouri / QOS-React-1 / commits / fd0da3eef1

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__