@samitouri / QOS-React / commits / b039be627d

Unrevert "Support writing to this.refs from userspace" (#28879)

Reverts facebook/react#28877 We found the cause of the regression and should be able to land this again.

Jan Kassens committed Apr 24, 2024 at 10:03 UTC b039be627dd7403d7d2f63a48c8d263d955ce456
3 files changed +35 -11
packages/react-reconciler/src/ReactFiberClassComponent.js
+9 -3
@@ -19,12 +19,13 @@ import {
19 } from './ReactFiberFlags';
20 import {
21 debugRenderPhaseSideEffectsForStrictMode,
22 + disableDefaultPropsExceptForClasses,
23 disableLegacyContext,
24 + disableStringRefs,
25 enableDebugTracing,
24 - enableSchedulingProfiler,
26 enableLazyContextPropagation,
27 enableRefAsProp,
27 - disableDefaultPropsExceptForClasses,
28 + enableSchedulingProfiler,
29 } from 'shared/ReactFeatureFlags';
30 import ReactStrictModeWarnings from './ReactStrictModeWarnings';
31 import {isMounted} from './ReactFiberTreeReflection';
@@ -819,7 +820,12 @@ function mountClassInstance(
820 const instance = workInProgress.stateNode;
821 instance.props = newProps;
822 instance.state = workInProgress.memoizedState;
822 - instance.refs = {};
823 + if (!disableStringRefs) {
824 + // When string refs are used in create-react-class legacy components,
825 + // we need to make refs writable unless we patch all such copies of the
826 + // class code that sets to a frozen emptyObject.
827 + instance.refs = {};
828 + }
829
830 initializeUpdateQueue(workInProgress);
831
packages/react-reconciler/src/__tests__/ReactFiberRefs-test.js
+24
@@ -138,4 +138,28 @@ describe('ReactFiberRefs', () => {
138 );
139 expect(refProp).toBe('child');
140 });
141 +
142 + test('strings refs can be codemodded to callback refs', async () => {
143 + let app;
144 + class App extends React.Component {
145 + render() {
146 + app = this;
147 + return (
148 + <div
149 + prop="Hello!"
150 + ref={el => {
151 + // `refs` used to be a shared frozen object unless/until a string
152 + // ref attached by the reconciler, but it's not anymore so that we
153 + // can codemod string refs to userspace callback refs.
154 + this.refs.div = el;
155 + }}
156 + />
157 + );
158 + }
159 + }
160 +
161 + const root = ReactNoop.createRoot();
162 + await act(() => root.render(<App />));
163 + expect(app.refs.div.prop).toBe('Hello!');
164 + });
165 });
packages/react/src/ReactBaseClasses.js
+2 -8
@@ -8,19 +8,13 @@
8 import ReactNoopUpdateQueue from './ReactNoopUpdateQueue';
9 import assign from 'shared/assign';
10
11 -const emptyObject = {};
12 -if (__DEV__) {
13 - Object.freeze(emptyObject);
14 -}
15 -
11 /**
12 * Base class helpers for the updating state of a component.
13 */
14 function Component(props, context, updater) {
15 this.props = props;
16 this.context = context;
22 - // If a component has string refs, we will assign a different object later.
23 - this.refs = emptyObject;
17 + this.refs = {};
18 // We initialize the default updater but the real one gets injected by the
19 // renderer.
20 this.updater = updater || ReactNoopUpdateQueue;
@@ -133,7 +127,7 @@ function PureComponent(props, context, updater) {
127 this.props = props;
128 this.context = context;
129 // If a component has string refs, we will assign a different object later.
136 - this.refs = emptyObject;
130 + this.refs = {};
131 this.updater = updater || ReactNoopUpdateQueue;
132 }
133