@samitouri / QOS-React / commits / d65b88d031

Eagerly initialize an mutable object for instance.refs (#25696)

This micro-optimization never made sense and less so now that they're rare. This still initializes the class with a shared immutable object in the constructor - which is also what createClass() does. Then we override it during mount. This is done in case someone messes up the initialization of the super() constructor for example, which was more common in polyfills. This change means that if a ref is initialized during the constructor itself it wouldn't be lazily initialized but that's not user code that does it, it's React so that shouldn't happen. This makes string refs codemoddable as described in. https://github.com/facebook/react/pull/25334

Sebastian Markbåge committed Nov 16, 2022 at 15:16 UTC d65b88d0319b37eec59c74ed9189cf5ab18b56e8
4 files changed +4 -28
packages/react-reconciler/src/ReactChildFiber.new.js
+1 -6
@@ -39,7 +39,6 @@ import {
39 createFiberFromText,
40 createFiberFromPortal,
41 } from './ReactFiber.new';
42 -import {emptyRefsObject} from './ReactFiberClassComponent.new';
42 import {isCompatibleFamilyForHotReloading} from './ReactFiberHotReloading.new';
43 import {StrictLegacyMode} from './ReactTypeOfMode';
44 import {getIsHydrating} from './ReactFiberHydrationContext.new';
@@ -192,11 +191,7 @@ function coerceRef(
191 return current.ref;
192 }
193 const ref = function(value) {
195 - let refs = resolvedInst.refs;
196 - if (refs === emptyRefsObject) {
197 - // This is a lazy pooled frozen object, so we need to initialize.
198 - refs = resolvedInst.refs = {};
199 - }
194 + const refs = resolvedInst.refs;
195 if (value === null) {
196 delete refs[stringRef];
197 } else {
packages/react-reconciler/src/ReactChildFiber.old.js
+1 -6
@@ -39,7 +39,6 @@ import {
39 createFiberFromText,
40 createFiberFromPortal,
41 } from './ReactFiber.old';
42 -import {emptyRefsObject} from './ReactFiberClassComponent.old';
42 import {isCompatibleFamilyForHotReloading} from './ReactFiberHotReloading.old';
43 import {StrictLegacyMode} from './ReactTypeOfMode';
44 import {getIsHydrating} from './ReactFiberHydrationContext.old';
@@ -192,11 +191,7 @@ function coerceRef(
191 return current.ref;
192 }
193 const ref = function(value) {
195 - let refs = resolvedInst.refs;
196 - if (refs === emptyRefsObject) {
197 - // This is a lazy pooled frozen object, so we need to initialize.
198 - refs = resolvedInst.refs = {};
199 - }
194 + const refs = resolvedInst.refs;
195 if (value === null) {
196 delete refs[stringRef];
197 } else {
packages/react-reconciler/src/ReactFiberClassComponent.new.js
+1 -8
@@ -12,7 +12,6 @@ import type {Lanes} from './ReactFiberLane.new';
12 import type {UpdateQueue} from './ReactFiberClassUpdateQueue.new';
13 import type {Flags} from './ReactFiberFlags';
14
15 -import * as React from 'react';
15 import {
16 LayoutStatic,
17 Update,
@@ -80,12 +79,6 @@ import {
79
80 const fakeInternalInstance = {};
81
83 -// React.Component uses a shared frozen object by default.
84 -// We'll use it to determine whether we need to initialize legacy refs.
85 -export const emptyRefsObject: $FlowFixMe = React.Component
86 - ? new React.Component().refs
87 - : {};
88 -
82 let didWarnAboutStateAssignmentForComponent;
83 let didWarnAboutUninitializedState;
84 let didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate;
@@ -836,7 +829,7 @@ function mountClassInstance(
829 const instance = workInProgress.stateNode;
830 instance.props = newProps;
831 instance.state = workInProgress.memoizedState;
839 - instance.refs = emptyRefsObject;
832 + instance.refs = {};
833
834 initializeUpdateQueue(workInProgress);
835
packages/react-reconciler/src/ReactFiberClassComponent.old.js
+1 -8
@@ -12,7 +12,6 @@ import type {Lanes} from './ReactFiberLane.old';
12 import type {UpdateQueue} from './ReactFiberClassUpdateQueue.old';
13 import type {Flags} from './ReactFiberFlags';
14
15 -import * as React from 'react';
15 import {
16 LayoutStatic,
17 Update,
@@ -80,12 +79,6 @@ import {
79
80 const fakeInternalInstance = {};
81
83 -// React.Component uses a shared frozen object by default.
84 -// We'll use it to determine whether we need to initialize legacy refs.
85 -export const emptyRefsObject: $FlowFixMe = React.Component
86 - ? new React.Component().refs
87 - : {};
88 -
82 let didWarnAboutStateAssignmentForComponent;
83 let didWarnAboutUninitializedState;
84 let didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate;
@@ -836,7 +829,7 @@ function mountClassInstance(
829 const instance = workInProgress.stateNode;
830 instance.props = newProps;
831 instance.state = workInProgress.memoizedState;
839 - instance.refs = emptyRefsObject;
832 + instance.refs = {};
833
834 initializeUpdateQueue(workInProgress);
835