Skip to content

Commit

Permalink
Unrevert "Support writing to this.refs from userspace" (#28879)
Browse files Browse the repository at this point in the history
Reverts #28877

We found the cause of the regression and should be able to land this
again.
  • Loading branch information
kassens authored Apr 24, 2024
1 parent 6f6e375 commit b039be6
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 11 deletions.
12 changes: 9 additions & 3 deletions packages/react-reconciler/src/ReactFiberClassComponent.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,13 @@ import {
} from './ReactFiberFlags';
import {
debugRenderPhaseSideEffectsForStrictMode,
disableDefaultPropsExceptForClasses,
disableLegacyContext,
disableStringRefs,
enableDebugTracing,
enableSchedulingProfiler,
enableLazyContextPropagation,
enableRefAsProp,
disableDefaultPropsExceptForClasses,
enableSchedulingProfiler,
} from 'shared/ReactFeatureFlags';
import ReactStrictModeWarnings from './ReactStrictModeWarnings';
import {isMounted} from './ReactFiberTreeReflection';
Expand Down Expand Up @@ -819,7 +820,12 @@ function mountClassInstance(
const instance = workInProgress.stateNode;
instance.props = newProps;
instance.state = workInProgress.memoizedState;
instance.refs = {};
if (!disableStringRefs) {
// When string refs are used in create-react-class legacy components,
// we need to make refs writable unless we patch all such copies of the
// class code that sets to a frozen emptyObject.
instance.refs = {};
}

initializeUpdateQueue(workInProgress);

Expand Down
24 changes: 24 additions & 0 deletions packages/react-reconciler/src/__tests__/ReactFiberRefs-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -138,4 +138,28 @@ describe('ReactFiberRefs', () => {
);
expect(refProp).toBe('child');
});

test('strings refs can be codemodded to callback refs', async () => {
let app;
class App extends React.Component {
render() {
app = this;
return (
<div
prop="Hello!"
ref={el => {
// `refs` used to be a shared frozen object unless/until a string
// ref attached by the reconciler, but it's not anymore so that we
// can codemod string refs to userspace callback refs.
this.refs.div = el;
}}
/>
);
}
}

const root = ReactNoop.createRoot();
await act(() => root.render(<App />));
expect(app.refs.div.prop).toBe('Hello!');
});
});
10 changes: 2 additions & 8 deletions packages/react/src/ReactBaseClasses.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,13 @@
import ReactNoopUpdateQueue from './ReactNoopUpdateQueue';
import assign from 'shared/assign';

const emptyObject = {};
if (__DEV__) {
Object.freeze(emptyObject);
}

/**
* Base class helpers for the updating state of a component.
*/
function Component(props, context, updater) {
this.props = props;
this.context = context;
// If a component has string refs, we will assign a different object later.
this.refs = emptyObject;
this.refs = {};
// We initialize the default updater but the real one gets injected by the
// renderer.
this.updater = updater || ReactNoopUpdateQueue;
Expand Down Expand Up @@ -133,7 +127,7 @@ function PureComponent(props, context, updater) {
this.props = props;
this.context = context;
// If a component has string refs, we will assign a different object later.
this.refs = emptyObject;
this.refs = {};
this.updater = updater || ReactNoopUpdateQueue;
}

Expand Down

0 comments on commit b039be6

Please sign in to comment.