From 6c606df0a63ad590ec0e06329a5a8106a0f7672b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Markb=C3=A5ge?= Date: Wed, 16 Nov 2022 15:16:54 -0500 Subject: [PATCH] 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 --- packages/react-reconciler/src/ReactChildFiber.new.js | 7 +------ packages/react-reconciler/src/ReactChildFiber.old.js | 7 +------ .../react-reconciler/src/ReactFiberClassComponent.new.js | 9 +-------- .../react-reconciler/src/ReactFiberClassComponent.old.js | 9 +-------- 4 files changed, 4 insertions(+), 28 deletions(-) diff --git a/packages/react-reconciler/src/ReactChildFiber.new.js b/packages/react-reconciler/src/ReactChildFiber.new.js index 07cacc0dbbf8f..6a984baec0c22 100644 --- a/packages/react-reconciler/src/ReactChildFiber.new.js +++ b/packages/react-reconciler/src/ReactChildFiber.new.js @@ -39,7 +39,6 @@ import { createFiberFromText, createFiberFromPortal, } from './ReactFiber.new'; -import {emptyRefsObject} from './ReactFiberClassComponent.new'; import {isCompatibleFamilyForHotReloading} from './ReactFiberHotReloading.new'; import {StrictLegacyMode} from './ReactTypeOfMode'; import {getIsHydrating} from './ReactFiberHydrationContext.new'; @@ -192,11 +191,7 @@ function coerceRef( return current.ref; } const ref = function(value) { - let refs = resolvedInst.refs; - if (refs === emptyRefsObject) { - // This is a lazy pooled frozen object, so we need to initialize. - refs = resolvedInst.refs = {}; - } + const refs = resolvedInst.refs; if (value === null) { delete refs[stringRef]; } else { diff --git a/packages/react-reconciler/src/ReactChildFiber.old.js b/packages/react-reconciler/src/ReactChildFiber.old.js index 7bad30d0d3ce6..8b6d4b8130dbd 100644 --- a/packages/react-reconciler/src/ReactChildFiber.old.js +++ b/packages/react-reconciler/src/ReactChildFiber.old.js @@ -39,7 +39,6 @@ import { createFiberFromText, createFiberFromPortal, } from './ReactFiber.old'; -import {emptyRefsObject} from './ReactFiberClassComponent.old'; import {isCompatibleFamilyForHotReloading} from './ReactFiberHotReloading.old'; import {StrictLegacyMode} from './ReactTypeOfMode'; import {getIsHydrating} from './ReactFiberHydrationContext.old'; @@ -192,11 +191,7 @@ function coerceRef( return current.ref; } const ref = function(value) { - let refs = resolvedInst.refs; - if (refs === emptyRefsObject) { - // This is a lazy pooled frozen object, so we need to initialize. - refs = resolvedInst.refs = {}; - } + const refs = resolvedInst.refs; if (value === null) { delete refs[stringRef]; } else { diff --git a/packages/react-reconciler/src/ReactFiberClassComponent.new.js b/packages/react-reconciler/src/ReactFiberClassComponent.new.js index 67352b1ca1867..14524865749d8 100644 --- a/packages/react-reconciler/src/ReactFiberClassComponent.new.js +++ b/packages/react-reconciler/src/ReactFiberClassComponent.new.js @@ -12,7 +12,6 @@ import type {Lanes} from './ReactFiberLane.new'; import type {UpdateQueue} from './ReactFiberClassUpdateQueue.new'; import type {Flags} from './ReactFiberFlags'; -import * as React from 'react'; import { LayoutStatic, Update, @@ -80,12 +79,6 @@ import { const fakeInternalInstance = {}; -// React.Component uses a shared frozen object by default. -// We'll use it to determine whether we need to initialize legacy refs. -export const emptyRefsObject: $FlowFixMe = React.Component - ? new React.Component().refs - : {}; - let didWarnAboutStateAssignmentForComponent; let didWarnAboutUninitializedState; let didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate; @@ -836,7 +829,7 @@ function mountClassInstance( const instance = workInProgress.stateNode; instance.props = newProps; instance.state = workInProgress.memoizedState; - instance.refs = emptyRefsObject; + instance.refs = {}; initializeUpdateQueue(workInProgress); diff --git a/packages/react-reconciler/src/ReactFiberClassComponent.old.js b/packages/react-reconciler/src/ReactFiberClassComponent.old.js index 78962f3587ac2..295367d7a906b 100644 --- a/packages/react-reconciler/src/ReactFiberClassComponent.old.js +++ b/packages/react-reconciler/src/ReactFiberClassComponent.old.js @@ -12,7 +12,6 @@ import type {Lanes} from './ReactFiberLane.old'; import type {UpdateQueue} from './ReactFiberClassUpdateQueue.old'; import type {Flags} from './ReactFiberFlags'; -import * as React from 'react'; import { LayoutStatic, Update, @@ -80,12 +79,6 @@ import { const fakeInternalInstance = {}; -// React.Component uses a shared frozen object by default. -// We'll use it to determine whether we need to initialize legacy refs. -export const emptyRefsObject: $FlowFixMe = React.Component - ? new React.Component().refs - : {}; - let didWarnAboutStateAssignmentForComponent; let didWarnAboutUninitializedState; let didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate; @@ -836,7 +829,7 @@ function mountClassInstance( const instance = workInProgress.stateNode; instance.props = newProps; instance.state = workInProgress.memoizedState; - instance.refs = emptyRefsObject; + instance.refs = {}; initializeUpdateQueue(workInProgress);