Skip to content

Commit 468b11f

Browse files
sebmarkbagerickhanlonii
authored andcommitted
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. #25334
1 parent f636a1b commit 468b11f

File tree

4 files changed

+4
-28
lines changed

4 files changed

+4
-28
lines changed

packages/react-reconciler/src/ReactChildFiber.new.js

+1-6
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ import {
3939
createFiberFromText,
4040
createFiberFromPortal,
4141
} from './ReactFiber.new';
42-
import {emptyRefsObject} from './ReactFiberClassComponent.new';
4342
import {isCompatibleFamilyForHotReloading} from './ReactFiberHotReloading.new';
4443
import {StrictLegacyMode} from './ReactTypeOfMode';
4544
import {getIsHydrating} from './ReactFiberHydrationContext.new';
@@ -192,11 +191,7 @@ function coerceRef(
192191
return current.ref;
193192
}
194193
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;
200195
if (value === null) {
201196
delete refs[stringRef];
202197
} else {

packages/react-reconciler/src/ReactChildFiber.old.js

+1-6
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ import {
3939
createFiberFromText,
4040
createFiberFromPortal,
4141
} from './ReactFiber.old';
42-
import {emptyRefsObject} from './ReactFiberClassComponent.old';
4342
import {isCompatibleFamilyForHotReloading} from './ReactFiberHotReloading.old';
4443
import {StrictLegacyMode} from './ReactTypeOfMode';
4544
import {getIsHydrating} from './ReactFiberHydrationContext.old';
@@ -192,11 +191,7 @@ function coerceRef(
192191
return current.ref;
193192
}
194193
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;
200195
if (value === null) {
201196
delete refs[stringRef];
202197
} else {

packages/react-reconciler/src/ReactFiberClassComponent.new.js

+1-8
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import type {Lanes} from './ReactFiberLane.new';
1212
import type {UpdateQueue} from './ReactFiberClassUpdateQueue.new';
1313
import type {Flags} from './ReactFiberFlags';
1414

15-
import * as React from 'react';
1615
import {
1716
LayoutStatic,
1817
Update,
@@ -80,12 +79,6 @@ import {
8079

8180
const fakeInternalInstance = {};
8281

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-
8982
let didWarnAboutStateAssignmentForComponent;
9083
let didWarnAboutUninitializedState;
9184
let didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate;
@@ -836,7 +829,7 @@ function mountClassInstance(
836829
const instance = workInProgress.stateNode;
837830
instance.props = newProps;
838831
instance.state = workInProgress.memoizedState;
839-
instance.refs = emptyRefsObject;
832+
instance.refs = {};
840833

841834
initializeUpdateQueue(workInProgress);
842835

packages/react-reconciler/src/ReactFiberClassComponent.old.js

+1-8
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import type {Lanes} from './ReactFiberLane.old';
1212
import type {UpdateQueue} from './ReactFiberClassUpdateQueue.old';
1313
import type {Flags} from './ReactFiberFlags';
1414

15-
import * as React from 'react';
1615
import {
1716
LayoutStatic,
1817
Update,
@@ -80,12 +79,6 @@ import {
8079

8180
const fakeInternalInstance = {};
8281

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-
8982
let didWarnAboutStateAssignmentForComponent;
9083
let didWarnAboutUninitializedState;
9184
let didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate;
@@ -836,7 +829,7 @@ function mountClassInstance(
836829
const instance = workInProgress.stateNode;
837830
instance.props = newProps;
838831
instance.state = workInProgress.memoizedState;
839-
instance.refs = emptyRefsObject;
832+
instance.refs = {};
840833

841834
initializeUpdateQueue(workInProgress);
842835

0 commit comments

Comments
 (0)