diff --git a/packages/jest-react/src/JestReact.js b/packages/jest-react/src/JestReact.js index 4eefc58c85228..8fcec97f63f7a 100644 --- a/packages/jest-react/src/JestReact.js +++ b/packages/jest-react/src/JestReact.js @@ -6,7 +6,7 @@ */ import {REACT_ELEMENT_TYPE, REACT_FRAGMENT_TYPE} from 'shared/ReactSymbols'; -import {disableStringRefs, enableRefAsProp} from 'shared/ReactFeatureFlags'; +import {disableStringRefs} from 'shared/ReactFeatureFlags'; const {assertConsoleLogsCleared} = require('internal-test-utils/consoleMock'); import isArray from 'shared/isArray'; @@ -42,7 +42,7 @@ function assertYieldsWereCleared(root) { } function createJSXElementForTestComparison(type, props) { - if (__DEV__ && enableRefAsProp) { + if (__DEV__) { const element = { $$typeof: REACT_ELEMENT_TYPE, type: type, diff --git a/packages/react-client/src/ReactFlightClient.js b/packages/react-client/src/ReactFlightClient.js index c0d599297858e..18a90349f5810 100644 --- a/packages/react-client/src/ReactFlightClient.js +++ b/packages/react-client/src/ReactFlightClient.js @@ -41,7 +41,6 @@ import { disableStringRefs, enableBinaryFlight, enablePostpone, - enableRefAsProp, enableFlightReadableStream, enableOwnerStacks, } from 'shared/ReactFeatureFlags'; @@ -630,7 +629,7 @@ function createElement( | React$Element | LazyComponent, SomeChunk>> { let element: any; - if (__DEV__ && enableRefAsProp) { + if (__DEV__) { // `ref` is non-enumerable in dev element = ({ $$typeof: REACT_ELEMENT_TYPE, diff --git a/packages/react-devtools-shared/src/__tests__/legacy/storeLegacy-v15-test.js b/packages/react-devtools-shared/src/__tests__/legacy/storeLegacy-v15-test.js index f912638fb508e..64261d07a7e18 100644 --- a/packages/react-devtools-shared/src/__tests__/legacy/storeLegacy-v15-test.js +++ b/packages/react-devtools-shared/src/__tests__/legacy/storeLegacy-v15-test.js @@ -873,7 +873,7 @@ describe('Store (legacy)', () => { // is not compatible with older versions of React. Need to configure the // the test environment in such a way that certain test modules like this // one can use an older transform. - if (!require('shared/ReactFeatureFlags').enableRefAsProp) { + if (false) { it('should support expanding deep parts of the tree', () => { const Wrapper = ({forwardedRef}) => React.createElement(Nested, { diff --git a/packages/react-dom/src/__tests__/ReactFunctionComponent-test.js b/packages/react-dom/src/__tests__/ReactFunctionComponent-test.js index 6a70f22db917c..24f97520ecc3d 100644 --- a/packages/react-dom/src/__tests__/ReactFunctionComponent-test.js +++ b/packages/react-dom/src/__tests__/ReactFunctionComponent-test.js @@ -197,223 +197,6 @@ describe('ReactFunctionComponent', () => { .rejects.toThrowError(); }); - // @gate !enableRefAsProp || !__DEV__ - it('should warn when given a string ref', async () => { - function Indirection(props) { - return
{props.children}
; - } - - class ParentUsingStringRef extends React.Component { - render() { - return ( - - - - ); - } - } - - await expect(async () => { - const container = document.createElement('div'); - const root = ReactDOMClient.createRoot(container); - await act(() => { - root.render(); - }); - }).toErrorDev( - 'Function components cannot be given refs. ' + - 'Attempts to access this ref will fail. ' + - 'Did you mean to use React.forwardRef()?\n\n' + - 'Check the render method ' + - 'of `ParentUsingStringRef`.\n' + - ' in FunctionComponent (at **)\n' + - ' in div (at **)\n' + - ' in Indirection (at **)\n' + - ' in ParentUsingStringRef (at **)', - ); - - // No additional warnings should be logged - const container = document.createElement('div'); - const root = ReactDOMClient.createRoot(container); - await act(() => { - root.render(); - }); - }); - - // @gate !enableRefAsProp || !__DEV__ - it('should warn when given a function ref', async () => { - function Indirection(props) { - return
{props.children}
; - } - - const ref = jest.fn(); - class ParentUsingFunctionRef extends React.Component { - render() { - return ( - - - - ); - } - } - - await expect(async () => { - const container = document.createElement('div'); - const root = ReactDOMClient.createRoot(container); - await act(() => { - root.render(); - }); - }).toErrorDev( - 'Function components cannot be given refs. ' + - 'Attempts to access this ref will fail. ' + - 'Did you mean to use React.forwardRef()?\n\n' + - 'Check the render method ' + - 'of `ParentUsingFunctionRef`.\n' + - ' in FunctionComponent (at **)\n' + - ' in div (at **)\n' + - ' in Indirection (at **)\n' + - ' in ParentUsingFunctionRef (at **)', - ); - expect(ref).not.toHaveBeenCalled(); - - // No additional warnings should be logged - const container = document.createElement('div'); - const root = ReactDOMClient.createRoot(container); - await act(() => { - root.render(); - }); - }); - - // @gate !enableRefAsProp || !__DEV__ - it('deduplicates ref warnings based on element or owner', async () => { - // When owner uses JSX, we can use exact line location to dedupe warnings - class AnonymousParentUsingJSX extends React.Component { - render() { - return {}} />; - } - } - - let instance1; - - await expect(async () => { - const container = document.createElement('div'); - const root = ReactDOMClient.createRoot(container); - - await act(() => { - root.render( - (instance1 = current)} />, - ); - }); - }).toErrorDev('Function components cannot be given refs.'); - // Should be deduped (offending element is on the same line): - instance1.forceUpdate(); - // Should also be deduped (offending element is on the same line): - let container = document.createElement('div'); - let root = ReactDOMClient.createRoot(container); - await act(() => { - root.render(); - }); - - // When owner doesn't use JSX, and is anonymous, we warn once per internal instance. - class AnonymousParentNotUsingJSX extends React.Component { - render() { - return React.createElement(FunctionComponent, { - name: 'A', - ref: () => {}, - }); - } - } - - let instance2; - await expect(async () => { - container = document.createElement('div'); - root = ReactDOMClient.createRoot(container); - await act(() => { - root.render( - (instance2 = current)} />, - ); - }); - }).toErrorDev('Function components cannot be given refs.'); - // Should be deduped (same internal instance, no additional warnings) - instance2.forceUpdate(); - // Could not be differentiated (since owner is anonymous and no source location) - container = document.createElement('div'); - root = ReactDOMClient.createRoot(container); - await act(() => { - root.render(); - }); - - // When owner doesn't use JSX, but is named, we warn once per owner name - class NamedParentNotUsingJSX extends React.Component { - render() { - return React.createElement(FunctionComponent, { - name: 'A', - ref: () => {}, - }); - } - } - let instance3; - await expect(async () => { - container = document.createElement('div'); - root = ReactDOMClient.createRoot(container); - await act(() => { - root.render( - (instance3 = current)} />, - ); - }); - }).toErrorDev('Function components cannot be given refs.'); - // Should be deduped (same owner name, no additional warnings): - instance3.forceUpdate(); - // Should also be deduped (same owner name, no additional warnings): - container = document.createElement('div'); - root = ReactDOMClient.createRoot(container); - await act(() => { - root.render(); - }); - }); - - // This guards against a regression caused by clearing the current debug fiber. - // https://github.com/facebook/react/issues/10831 - // @gate !disableLegacyContext || !__DEV__ - // @gate !enableRefAsProp || !__DEV__ - it('should warn when giving a function ref with context', async () => { - function Child() { - return null; - } - Child.contextTypes = { - foo: PropTypes.string, - }; - - class Parent extends React.Component { - static childContextTypes = { - foo: PropTypes.string, - }; - getChildContext() { - return { - foo: 'bar', - }; - } - render() { - return ; - } - } - - await expect(async () => { - const container = document.createElement('div'); - const root = ReactDOMClient.createRoot(container); - await act(() => { - root.render(); - }); - }).toErrorDev( - 'Function components cannot be given refs. ' + - 'Attempts to access this ref will fail. ' + - 'Did you mean to use React.forwardRef()?\n\n' + - 'Check the render method ' + - 'of `Parent`.\n' + - ' in Child (at **)\n' + - ' in Parent (at **)', - ); - }); - it('should use correct name in key warning', async () => { function Child() { return
{[]}
; diff --git a/packages/react-dom/src/__tests__/refs-test.js b/packages/react-dom/src/__tests__/refs-test.js index 1b081bff73b02..80ea8d1e26b32 100644 --- a/packages/react-dom/src/__tests__/refs-test.js +++ b/packages/react-dom/src/__tests__/refs-test.js @@ -369,24 +369,6 @@ describe('ref swapping', () => { }); }).rejects.toThrow('Expected ref to be a function'); }); - - // @gate !enableRefAsProp && www - it('undefined ref on manually inlined React element triggers error', async () => { - const container = document.createElement('div'); - const root = ReactDOMClient.createRoot(container); - await expect(async () => { - await act(() => { - root.render({ - $$typeof: Symbol.for('react.element'), - type: 'div', - props: { - ref: undefined, - }, - key: null, - }); - }); - }).rejects.toThrow('Expected ref to be a function'); - }); }); describe('root level refs', () => { diff --git a/packages/react-noop-renderer/src/createReactNoop.js b/packages/react-noop-renderer/src/createReactNoop.js index a7cfc94e00a15..6d9d3ab1368d3 100644 --- a/packages/react-noop-renderer/src/createReactNoop.js +++ b/packages/react-noop-renderer/src/createReactNoop.js @@ -35,11 +35,7 @@ import { ConcurrentRoot, LegacyRoot, } from 'react-reconciler/constants'; -import { - enableRefAsProp, - disableLegacyMode, - disableStringRefs, -} from 'shared/ReactFeatureFlags'; +import {disableLegacyMode, disableStringRefs} from 'shared/ReactFeatureFlags'; import ReactSharedInternals from 'shared/ReactSharedInternals'; @@ -816,7 +812,7 @@ function createReactNoop(reconciler: Function, useMutation: boolean) { let currentEventPriority = DefaultEventPriority; function createJSXElementForTestComparison(type, props) { - if (__DEV__ && enableRefAsProp) { + if (__DEV__) { const element = { type: type, $$typeof: REACT_ELEMENT_TYPE, diff --git a/packages/react-reconciler/src/ReactChildFiber.js b/packages/react-reconciler/src/ReactChildFiber.js index d4cf9db2d9c19..7d82b44f68eab 100644 --- a/packages/react-reconciler/src/ReactChildFiber.js +++ b/packages/react-reconciler/src/ReactChildFiber.js @@ -45,7 +45,6 @@ import { } from './ReactWorkTags'; import isArray from 'shared/isArray'; import { - enableRefAsProp, enableAsyncIterableChildren, disableLegacyMode, enableOwnerStacks, @@ -239,21 +238,6 @@ function validateFragmentProps( break; } } - - if (!enableRefAsProp && element.ref !== null) { - if (fiber === null) { - // For unkeyed root fragments there's no Fiber. We create a fake one just for - // error stack handling. - fiber = createFiberFromElement(element, returnFiber.mode, 0); - if (__DEV__) { - fiber._debugInfo = currentDebugInfo; - } - fiber.return = returnFiber; - } - runWithFiberInDEV(fiber, () => { - console.error('Invalid attribute `ref` supplied to `React.Fragment`.'); - }); - } } } @@ -272,21 +256,13 @@ function coerceRef( workInProgress: Fiber, element: ReactElement, ): void { - let ref; - if (enableRefAsProp) { - // TODO: This is a temporary, intermediate step. When enableRefAsProp is on, - // we should resolve the `ref` prop during the begin phase of the component - // it's attached to (HostComponent, ClassComponent, etc). - const refProp = element.props.ref; - ref = refProp !== undefined ? refProp : null; - } else { - // Old behavior. - ref = element.ref; - } - - // TODO: If enableRefAsProp is on, we shouldn't use the `ref` field. We + // TODO: This is a temporary, intermediate step. Now that enableRefAsProp is on, + // we should resolve the `ref` prop during the begin phase of the component + // it's attached to (HostComponent, ClassComponent, etc). + const refProp = element.props.ref; + // TODO: With enableRefAsProp now rolled out, we shouldn't use the `ref` field. We // should always read the ref from the prop. - workInProgress.ref = ref; + workInProgress.ref = refProp !== undefined ? refProp : null; } function throwOnInvalidObjectType(returnFiber: Fiber, newChild: Object) { diff --git a/packages/react-reconciler/src/ReactFiberBeginWork.js b/packages/react-reconciler/src/ReactFiberBeginWork.js index 98a89e018da97..a4b6449ee2d5d 100644 --- a/packages/react-reconciler/src/ReactFiberBeginWork.js +++ b/packages/react-reconciler/src/ReactFiberBeginWork.js @@ -108,7 +108,6 @@ import { enableAsyncActions, enablePostpone, enableRenderableContext, - enableRefAsProp, disableLegacyMode, disableDefaultPropsExceptForClasses, disableStringRefs, @@ -125,10 +124,7 @@ import { REACT_MEMO_TYPE, getIteratorFn, } from 'shared/ReactSymbols'; -import { - getCurrentFiberOwnerNameInDevOrNull, - setCurrentFiber, -} from './ReactCurrentFiber'; +import {setCurrentFiber} from './ReactCurrentFiber'; import { resolveFunctionForHotReloading, resolveForwardRefForHotReloading, @@ -319,7 +315,6 @@ let didWarnAboutBadClass; let didWarnAboutContextTypeOnFunctionComponent; let didWarnAboutContextTypes; let didWarnAboutGetDerivedStateOnFunctionComponent; -let didWarnAboutFunctionRefs; export let didWarnAboutReassigningProps: boolean; let didWarnAboutRevealOrder; let didWarnAboutTailOptions; @@ -330,7 +325,6 @@ if (__DEV__) { didWarnAboutContextTypeOnFunctionComponent = ({}: {[string]: boolean}); didWarnAboutContextTypes = ({}: {[string]: boolean}); didWarnAboutGetDerivedStateOnFunctionComponent = ({}: {[string]: boolean}); - didWarnAboutFunctionRefs = ({}: {[string]: boolean}); didWarnAboutReassigningProps = false; didWarnAboutRevealOrder = ({}: {[empty]: boolean}); didWarnAboutTailOptions = ({}: {[string]: boolean}); @@ -416,7 +410,7 @@ function updateForwardRef( const ref = workInProgress.ref; let propsWithoutRef; - if (enableRefAsProp && 'ref' in nextProps) { + if ('ref' in nextProps) { // `ref` is just a prop now, but `forwardRef` expects it to not appear in // the props object. This used to happen in the JSX runtime, but now we do // it here. @@ -1948,25 +1942,6 @@ function validateFunctionComponentInDev(workInProgress: Fiber, Component: any) { Component.displayName || Component.name || 'Component', ); } - if (!enableRefAsProp && workInProgress.ref !== null) { - let info = ''; - const componentName = getComponentNameFromType(Component) || 'Unknown'; - const ownerName = getCurrentFiberOwnerNameInDevOrNull(); - if (ownerName) { - info += '\n\nCheck the render method of `' + ownerName + '`.'; - } - - const warningKey = componentName + '|' + (ownerName || ''); - if (!didWarnAboutFunctionRefs[warningKey]) { - didWarnAboutFunctionRefs[warningKey] = true; - console.error( - 'Function components cannot be given refs. ' + - 'Attempts to access this ref will fail. ' + - 'Did you mean to use React.forwardRef()?%s', - info, - ); - } - } if ( !disableDefaultPropsExceptForClasses && diff --git a/packages/react-reconciler/src/ReactFiberClassComponent.js b/packages/react-reconciler/src/ReactFiberClassComponent.js index f1419d1aad047..2321f09e64f7f 100644 --- a/packages/react-reconciler/src/ReactFiberClassComponent.js +++ b/packages/react-reconciler/src/ReactFiberClassComponent.js @@ -23,7 +23,6 @@ import { enableDebugTracing, enableSchedulingProfiler, enableLazyContextPropagation, - enableRefAsProp, disableDefaultPropsExceptForClasses, } from 'shared/ReactFeatureFlags'; import ReactStrictModeWarnings from './ReactStrictModeWarnings'; @@ -1248,14 +1247,12 @@ export function resolveClassComponentProps( ): Object { let newProps = baseProps; - if (enableRefAsProp) { - // Remove ref from the props object, if it exists. - if ('ref' in baseProps) { - newProps = ({}: any); - for (const propName in baseProps) { - if (propName !== 'ref') { - newProps[propName] = baseProps[propName]; - } + // Remove ref from the props object, if it exists. + if ('ref' in baseProps) { + newProps = ({}: any); + for (const propName in baseProps) { + if (propName !== 'ref') { + newProps[propName] = baseProps[propName]; } } } diff --git a/packages/react-reconciler/src/__tests__/ReactFiberRefs-test.js b/packages/react-reconciler/src/__tests__/ReactFiberRefs-test.js index 2a0590af3171d..8fd5206c94ae4 100644 --- a/packages/react-reconciler/src/__tests__/ReactFiberRefs-test.js +++ b/packages/react-reconciler/src/__tests__/ReactFiberRefs-test.js @@ -85,7 +85,6 @@ describe('ReactFiberRefs', () => { expect(ref2.current).not.toBe(null); }); - // @gate enableRefAsProp // @gate !disableStringRefs it('string ref props are converted to function refs', async () => { let refProp; @@ -105,7 +104,7 @@ describe('ReactFiberRefs', () => { const root = ReactNoop.createRoot(); await act(() => root.render()); - // When string refs aren't disabled, and enableRefAsProp is on, string refs + // When string refs aren't disabled, string refs // the receiving component receives a callback ref, not the original string. // This behavior should never be shipped to open source; it's only here to // allow Meta to keep using string refs temporarily while they finish diff --git a/packages/react-reconciler/src/__tests__/ReactIncrementalSideEffects-test.js b/packages/react-reconciler/src/__tests__/ReactIncrementalSideEffects-test.js index 73600d9419309..4458674e19956 100644 --- a/packages/react-reconciler/src/__tests__/ReactIncrementalSideEffects-test.js +++ b/packages/react-reconciler/src/__tests__/ReactIncrementalSideEffects-test.js @@ -1299,20 +1299,7 @@ describe('ReactIncrementalSideEffects', () => { ReactNoop.render(); - if (gate(flags => flags.enableRefAsProp)) { - await waitForAll([]); - } else { - await expect(async () => await waitForAll([])).toErrorDev( - 'Function components cannot be given refs. ' + - 'Attempts to access this ref will fail. ' + - 'Did you mean to use React.forwardRef()?\n\n' + - 'Check the render method ' + - 'of `Foo`.\n' + - ' in FunctionComponent (at **)\n' + - ' in div (at **)\n' + - ' in Foo (at **)', - ); - } + await waitForAll([]); expect(ops).toEqual([ classInstance, diff --git a/packages/react-reconciler/src/__tests__/ReactLazy-test.internal.js b/packages/react-reconciler/src/__tests__/ReactLazy-test.internal.js index 644913a15fd9f..bdd65a8c15f7d 100644 --- a/packages/react-reconciler/src/__tests__/ReactLazy-test.internal.js +++ b/packages/react-reconciler/src/__tests__/ReactLazy-test.internal.js @@ -1191,30 +1191,6 @@ describe('ReactLazy', () => { expect(root).toMatchRenderedOutput('2'); }); - // @gate !enableRefAsProp || !__DEV__ - it('warns about ref on functions for lazy-loaded components', async () => { - const Foo = props =>
; - const LazyFoo = lazy(() => { - return fakeImport(Foo); - }); - - const ref = React.createRef(); - ReactTestRenderer.create( - }> - - , - { - unstable_isConcurrent: true, - }, - ); - - await waitForAll(['Loading...']); - await resolveFakeImport(Foo); - await expect(async () => { - await waitForAll([]); - }).toErrorDev('Function components cannot be given refs'); - }); - it('should error with a component stack naming the resolved component', async () => { let componentStackMessage; diff --git a/packages/react-reconciler/src/__tests__/ReactMemo-test.js b/packages/react-reconciler/src/__tests__/ReactMemo-test.js index c4d50631ec8ba..5fdf14af4d37b 100644 --- a/packages/react-reconciler/src/__tests__/ReactMemo-test.js +++ b/packages/react-reconciler/src/__tests__/ReactMemo-test.js @@ -44,43 +44,6 @@ describe('memo', () => { return {default: result}; } - // @gate !enableRefAsProp || !__DEV__ - it('warns when giving a ref (simple)', async () => { - // This test lives outside sharedTests because the wrappers don't forward - // refs properly, and they end up affecting the current owner which is used - // by the warning (making the messages not line up). - function App() { - return null; - } - App = React.memo(App); - function Outer() { - return {}} />; - } - ReactNoop.render(); - await expect(async () => await waitForAll([])).toErrorDev([ - 'Function components cannot be given refs. Attempts to access ' + - 'this ref will fail.', - ]); - }); - - // @gate !enableRefAsProp || !__DEV__ - it('warns when giving a ref (complex)', async () => { - function App() { - return null; - } - // A custom compare function means this won't use SimpleMemoComponent (as of this writing) - // SimpleMemoComponent is unobservable tho, so we can't check :) - App = React.memo(App, () => false); - function Outer() { - return {}} />; - } - ReactNoop.render(); - await expect(async () => await waitForAll([])).toErrorDev([ - 'Function components cannot be given refs. Attempts to access ' + - 'this ref will fail.', - ]); - }); - // Tests should run against both the lazy and non-lazy versions of `memo`. // To make the tests work for both versions, we wrap the non-lazy version in // a lazy function component. diff --git a/packages/react-server/src/ReactFizzServer.js b/packages/react-server/src/ReactFizzServer.js index e068db78dcf8a..044cd15f34a77 100644 --- a/packages/react-server/src/ReactFizzServer.js +++ b/packages/react-server/src/ReactFizzServer.js @@ -158,7 +158,6 @@ import { enableCache, enablePostpone, enableRenderableContext, - enableRefAsProp, disableDefaultPropsExceptForClasses, enableAsyncIterableChildren, disableStringRefs, @@ -1575,14 +1574,12 @@ export function resolveClassComponentProps( ): Object { let newProps = baseProps; - if (enableRefAsProp) { - // Remove ref from the props object, if it exists. - if ('ref' in baseProps) { - newProps = ({}: any); - for (const propName in baseProps) { - if (propName !== 'ref') { - newProps[propName] = baseProps[propName]; - } + // Remove ref from the props object, if it exists. + if ('ref' in baseProps) { + newProps = ({}: any); + for (const propName in baseProps) { + if (propName !== 'ref') { + newProps[propName] = baseProps[propName]; } } } @@ -1872,7 +1869,7 @@ function renderForwardRef( ref: any, ): void { let propsWithoutRef; - if (enableRefAsProp && 'ref' in props) { + if ('ref' in props) { // `ref` is just a prop now, but `forwardRef` expects it to not appear in // the props object. This used to happen in the JSX runtime, but now we do // it here. @@ -2490,16 +2487,11 @@ function retryNode(request: Request, task: Task): void { const key = element.key; const props = element.props; - let ref; - if (enableRefAsProp) { - // TODO: This is a temporary, intermediate step. Once the feature - // flag is removed, we should get the ref off the props object right - // before using it. - const refProp = props.ref; - ref = refProp !== undefined ? refProp : null; - } else { - ref = element.ref; - } + // TODO: This is a temporary, intermediate step. Once the feature + // flag is removed, we should get the ref off the props object right + // before using it. + const refProp = props.ref; + const ref = refProp !== undefined ? refProp : null; const debugTask: null | ConsoleTask = __DEV__ && enableOwnerStacks ? task.debugTask : null; diff --git a/packages/react-server/src/ReactFlightServer.js b/packages/react-server/src/ReactFlightServer.js index 1eaf5369c79c8..f68a824fe1bdc 100644 --- a/packages/react-server/src/ReactFlightServer.js +++ b/packages/react-server/src/ReactFlightServer.js @@ -17,7 +17,6 @@ import { enableBinaryFlight, enablePostpone, enableTaint, - enableRefAsProp, enableServerComponentLogs, enableOwnerStacks, } from 'shared/ReactFeatureFlags'; @@ -2312,16 +2311,11 @@ function renderModelDestructive( } const props = element.props; - let ref; - if (enableRefAsProp) { - // TODO: This is a temporary, intermediate step. Once the feature - // flag is removed, we should get the ref off the props object right - // before using it. - const refProp = props.ref; - ref = refProp !== undefined ? refProp : null; - } else { - ref = element.ref; - } + // TODO: This is a temporary, intermediate step. Once the feature + // flag is removed, we should get the ref off the props object right + // before using it. + const refProp = props.ref; + const ref = refProp !== undefined ? refProp : null; // Attempt to render the Server Component. diff --git a/packages/react-test-renderer/src/__tests__/ReactTestRenderer-test.internal.js b/packages/react-test-renderer/src/__tests__/ReactTestRenderer-test.internal.js index 4364d48f031c7..23ba7937ff1ab 100644 --- a/packages/react-test-renderer/src/__tests__/ReactTestRenderer-test.internal.js +++ b/packages/react-test-renderer/src/__tests__/ReactTestRenderer-test.internal.js @@ -386,39 +386,6 @@ describe('ReactTestRenderer', () => { expect(log).toEqual([null]); }); - // @gate !enableRefAsProp || !__DEV__ - it('warns correctly for refs on SFCs', async () => { - function Bar() { - return
Hello, world
; - } - class Foo extends React.Component { - fooRef = React.createRef(); - render() { - return ; - } - } - class Baz extends React.Component { - bazRef = React.createRef(); - render() { - return
; - } - } - await act(() => { - ReactTestRenderer.create(); - }); - await expect(async () => { - await act(() => { - ReactTestRenderer.create(); - }); - }).toErrorDev( - 'Function components cannot be given refs. Attempts ' + - 'to access this ref will fail. ' + - 'Did you mean to use React.forwardRef()?\n' + - ' in Bar (at **)\n' + - ' in Foo (at **)', - ); - }); - it('allows an optional createNodeMock function', async () => { const mockDivInstance = {appendChild: () => {}}; const mockInputInstance = {focus: () => {}}; @@ -1226,11 +1193,9 @@ describe('ReactTestRenderer', () => { { instance: null, nodeType: 'host', - props: gate(flags => flags.enableRefAsProp) - ? { - ref: refFn, - } - : {}, + props: { + ref: refFn, + }, rendered: [], type: 'span', }, diff --git a/packages/react/src/__tests__/ReactCreateElement-test.js b/packages/react/src/__tests__/ReactCreateElement-test.js index 51012166af260..3ab5c34c3304d 100644 --- a/packages/react/src/__tests__/ReactCreateElement-test.js +++ b/packages/react/src/__tests__/ReactCreateElement-test.js @@ -37,11 +37,7 @@ describe('ReactCreateElement', () => { const element = React.createElement(ComponentClass); expect(element.type).toBe(ComponentClass); expect(element.key).toBe(null); - if (gate(flags => flags.enableRefAsProp)) { - expect(element.ref).toBe(null); - } else { - expect(element.ref).toBe(null); - } + expect(element.ref).toBe(null); if (__DEV__) { expect(Object.isFrozen(element)).toBe(true); expect(Object.isFrozen(element.props)).toBe(true); @@ -90,45 +86,11 @@ describe('ReactCreateElement', () => { ); }); - // @gate !enableRefAsProp || !__DEV__ - it('should warn when `ref` is being accessed', async () => { - class Child extends React.Component { - render() { - return React.createElement('div', null, this.props.ref); - } - } - class Parent extends React.Component { - render() { - return React.createElement( - 'div', - null, - React.createElement(Child, {ref: React.createRef()}), - ); - } - } - const root = ReactDOMClient.createRoot(document.createElement('div')); - - await expect(async () => { - await act(() => { - root.render(React.createElement(Parent)); - }); - }).toErrorDev( - 'Child: `ref` is not a prop. Trying to access it will result ' + - 'in `undefined` being returned. If you need to access the same ' + - 'value within the child component, you should pass it as a different ' + - 'prop. (https://react.dev/link/special-props)', - ); - }); - it('allows a string to be passed as the type', () => { const element = React.createElement('div'); expect(element.type).toBe('div'); expect(element.key).toBe(null); - if (gate(flags => flags.enableRefAsProp)) { - expect(element.ref).toBe(null); - } else { - expect(element.ref).toBe(null); - } + expect(element.ref).toBe(null); if (__DEV__) { expect(Object.isFrozen(element)).toBe(true); expect(Object.isFrozen(element.props)).toBe(true); @@ -179,20 +141,13 @@ describe('ReactCreateElement', () => { foo: '56', }); expect(element.type).toBe(ComponentClass); - if (gate(flags => flags.enableRefAsProp)) { - expect(() => expect(element.ref).toBe(ref)).toErrorDev( - 'Accessing element.ref was removed in React 19', - {withoutStack: true}, - ); - const expectation = {foo: '56', ref}; - Object.freeze(expectation); - expect(element.props).toEqual(expectation); - } else { - const expectation = {foo: '56'}; - Object.freeze(expectation); - expect(element.props).toEqual(expectation); - expect(element.ref).toBe(ref); - } + expect(() => expect(element.ref).toBe(ref)).toErrorDev( + 'Accessing element.ref was removed in React 19', + {withoutStack: true}, + ); + const expectation = {foo: '56', ref}; + Object.freeze(expectation); + expect(element.props).toEqual(expectation); }); it('extracts null key', () => { @@ -218,11 +173,7 @@ describe('ReactCreateElement', () => { const element = React.createElement(ComponentClass, props); expect(element.type).toBe(ComponentClass); expect(element.key).toBe(null); - if (gate(flags => flags.enableRefAsProp)) { - expect(element.ref).toBe(null); - } else { - expect(element.ref).toBe(null); - } + expect(element.ref).toBe(null); if (__DEV__) { expect(Object.isFrozen(element)).toBe(true); expect(Object.isFrozen(element.props)).toBe(true); @@ -234,11 +185,7 @@ describe('ReactCreateElement', () => { const elementA = React.createElement('div'); const elementB = React.createElement('div', elementA.props); expect(elementB.key).toBe(null); - if (gate(flags => flags.enableRefAsProp)) { - expect(elementB.ref).toBe(null); - } else { - expect(elementB.ref).toBe(null); - } + expect(elementB.ref).toBe(null); }); it('coerces the key to a string', () => { @@ -248,11 +195,7 @@ describe('ReactCreateElement', () => { }); expect(element.type).toBe(ComponentClass); expect(element.key).toBe('12'); - if (gate(flags => flags.enableRefAsProp)) { - expect(element.ref).toBe(null); - } else { - expect(element.ref).toBe(null); - } + expect(element.ref).toBe(null); if (__DEV__) { expect(Object.isFrozen(element)).toBe(true); expect(Object.isFrozen(element.props)).toBe(true); diff --git a/packages/react/src/__tests__/ReactElementClone-test.js b/packages/react/src/__tests__/ReactElementClone-test.js index 1acf56749ed65..435af8e11804f 100644 --- a/packages/react/src/__tests__/ReactElementClone-test.js +++ b/packages/react/src/__tests__/ReactElementClone-test.js @@ -212,11 +212,7 @@ describe('ReactElementClone', () => { ref: this.xyzRef, }); expect(clone.key).toBe('xyz'); - if (gate(flags => flags.enableRefAsProp)) { - expect(clone.props.ref).toBe(this.xyzRef); - } else { - expect(clone.ref).toBe(this.xyzRef); - } + expect(clone.props.ref).toBe(this.xyzRef); return
{clone}
; } } @@ -274,17 +270,13 @@ describe('ReactElementClone', () => { const root = ReactDOMClient.createRoot(document.createElement('div')); await act(() => root.render()); - if (gate(flags => flags.enableRefAsProp && flags.disableStringRefs)) { + if (gate(flags => flags.disableStringRefs)) { expect(component.childRef).toEqual({current: null}); expect(component.parentRef.current.xyzRef.current.tagName).toBe('SPAN'); - } else if ( - gate(flags => !flags.enableRefAsProp && !flags.disableStringRefs) - ) { + } else if (gate(flags => false)) { expect(component.childRef).toEqual({current: null}); expect(component.parentRef.current.xyzRef.current.tagName).toBe('SPAN'); - } else if ( - gate(flags => flags.enableRefAsProp && !flags.disableStringRefs) - ) { + } else if (gate(flags => !flags.disableStringRefs)) { expect(component.childRef).toEqual({current: null}); expect(component.parentRef.current.xyzRef.current.tagName).toBe('SPAN'); } else { @@ -397,11 +389,7 @@ describe('ReactElementClone', () => { const elementA = React.createElement('div'); const elementB = React.cloneElement(elementA, elementA.props); expect(elementB.key).toBe(null); - if (gate(flags => flags.enableRefAsProp)) { - expect(elementB.ref).toBe(null); - } else { - expect(elementB.ref).toBe(null); - } + expect(elementB.ref).toBe(null); }); it('should ignore undefined key and ref', () => { @@ -418,21 +406,17 @@ describe('ReactElementClone', () => { const clone = React.cloneElement(element, props); expect(clone.type).toBe(ComponentClass); expect(clone.key).toBe('12'); - if (gate(flags => flags.enableRefAsProp && flags.disableStringRefs)) { + if (gate(flags => flags.disableStringRefs)) { expect(clone.props.ref).toBe('34'); expect(() => expect(clone.ref).toBe('34')).toErrorDev( 'Accessing element.ref was removed in React 19', {withoutStack: true}, ); expect(clone.props).toEqual({foo: 'ef', ref: '34'}); - } else if ( - gate(flags => !flags.enableRefAsProp && !flags.disableStringRefs) - ) { + } else if (gate(flags => false)) { expect(clone.ref).toBe(element.ref); expect(clone.props).toEqual({foo: 'ef'}); - } else if ( - gate(flags => flags.enableRefAsProp && !flags.disableStringRefs) - ) { + } else if (gate(flags => !flags.disableStringRefs)) { expect(() => { expect(clone.ref).toBe(element.ref); }).toErrorDev('Accessing element.ref was removed in React 19', { @@ -462,14 +446,8 @@ describe('ReactElementClone', () => { const clone = React.cloneElement(element, props); expect(clone.type).toBe(ComponentClass); expect(clone.key).toBe('null'); - if (gate(flags => flags.enableRefAsProp)) { - expect(clone.ref).toBe(null); - expect(clone.props).toEqual({foo: 'ef', ref: null}); - } else { - expect(clone.ref).toBe(null); - expect(clone.props).toEqual({foo: 'ef'}); - } - + expect(clone.ref).toBe(null); + expect(clone.props).toEqual({foo: 'ef', ref: null}); if (__DEV__) { expect(Object.isFrozen(element)).toBe(true); expect(Object.isFrozen(element.props)).toBe(true); diff --git a/packages/react/src/__tests__/ReactJSXElementValidator-test.js b/packages/react/src/__tests__/ReactJSXElementValidator-test.js index f827a52bc59ca..12e54e5c969cc 100644 --- a/packages/react/src/__tests__/ReactJSXElementValidator-test.js +++ b/packages/react/src/__tests__/ReactJSXElementValidator-test.js @@ -248,23 +248,13 @@ describe('ReactJSXElementValidator', () => { } } - if (gate(flags => flags.enableRefAsProp)) { - await expect(async () => { - const container = document.createElement('div'); - const root = ReactDOMClient.createRoot(container); - await act(() => { - root.render(); - }); - }).toErrorDev('Invalid prop `ref` supplied to `React.Fragment`.'); - } else { - await expect(async () => { - const container = document.createElement('div'); - const root = ReactDOMClient.createRoot(container); - await act(() => { - root.render(); - }); - }).toErrorDev('Invalid attribute `ref` supplied to `React.Fragment`.'); - } + await expect(async () => { + const container = document.createElement('div'); + const root = ReactDOMClient.createRoot(container); + await act(() => { + root.render(); + }); + }).toErrorDev('Invalid prop `ref` supplied to `React.Fragment`.'); }); it('does not warn for fragments of multiple elements without keys', async () => { diff --git a/packages/react/src/__tests__/ReactJSXRuntime-test.js b/packages/react/src/__tests__/ReactJSXRuntime-test.js index 8a63eca32607d..b80f9331a1ea9 100644 --- a/packages/react/src/__tests__/ReactJSXRuntime-test.js +++ b/packages/react/src/__tests__/ReactJSXRuntime-test.js @@ -244,34 +244,6 @@ describe('ReactJSXRuntime', () => { ); }); - // @gate !enableRefAsProp || !__DEV__ - it('should warn when `ref` is being accessed', async () => { - const container = document.createElement('div'); - class Child extends React.Component { - render() { - return JSXRuntime.jsx('div', {children: this.props.ref}); - } - } - class Parent extends React.Component { - render() { - return JSXRuntime.jsx('div', { - children: JSXRuntime.jsx(Child, {ref: React.createRef()}), - }); - } - } - await expect(async () => { - const root = ReactDOMClient.createRoot(container); - await act(() => { - root.render(JSXRuntime.jsx(Parent, {})); - }); - }).toErrorDev( - 'Child: `ref` is not a prop. Trying to access it will result ' + - 'in `undefined` being returned. If you need to access the same ' + - 'value within the child component, you should pass it as a different ' + - 'prop. (https://react.dev/link/special-props)', - ); - }); - it('should warn when unkeyed children are passed to jsx', async () => { const container = document.createElement('div'); @@ -377,7 +349,7 @@ describe('ReactJSXRuntime', () => { expect(didCall).toBe(false); }); - // @gate enableFastJSX && enableRefAsProp + // @gate enableFastJSX it('does not clone props object if key and ref is not spread', async () => { const config = { foo: 'foo', diff --git a/packages/react/src/__tests__/ReactJSXTransformIntegration-test.js b/packages/react/src/__tests__/ReactJSXTransformIntegration-test.js index 22480f1a7ef63..f0caf6b494ae1 100644 --- a/packages/react/src/__tests__/ReactJSXTransformIntegration-test.js +++ b/packages/react/src/__tests__/ReactJSXTransformIntegration-test.js @@ -55,11 +55,7 @@ describe('ReactJSXTransformIntegration', () => { const element = ; expect(element.type).toBe(Component); expect(element.key).toBe(null); - if (gate(flags => flags.enableRefAsProp)) { - expect(element.ref).toBe(null); - } else { - expect(element.ref).toBe(null); - } + expect(element.ref).toBe(null); const expectation = {}; Object.freeze(expectation); expect(element.props).toEqual(expectation); @@ -69,11 +65,7 @@ describe('ReactJSXTransformIntegration', () => { const element =
; expect(element.type).toBe('div'); expect(element.key).toBe(null); - if (gate(flags => flags.enableRefAsProp)) { - expect(element.ref).toBe(null); - } else { - expect(element.ref).toBe(null); - } + expect(element.ref).toBe(null); const expectation = {}; Object.freeze(expectation); expect(element.props).toEqual(expectation); @@ -84,11 +76,7 @@ describe('ReactJSXTransformIntegration', () => { const element = ; expect(element.type).toBe('div'); expect(element.key).toBe(null); - if (gate(flags => flags.enableRefAsProp)) { - expect(element.ref).toBe(null); - } else { - expect(element.ref).toBe(null); - } + expect(element.ref).toBe(null); const expectation = {}; Object.freeze(expectation); expect(element.props).toEqual(expectation); @@ -124,31 +112,20 @@ describe('ReactJSXTransformIntegration', () => { const ref = React.createRef(); const element = ; expect(element.type).toBe(Component); - if (gate(flags => flags.enableRefAsProp)) { - expect(() => expect(element.ref).toBe(ref)).toErrorDev( - 'Accessing element.ref was removed in React 19', - {withoutStack: true}, - ); - const expectation = {foo: '56', ref}; - Object.freeze(expectation); - expect(element.props).toEqual(expectation); - } else { - const expectation = {foo: '56'}; - Object.freeze(expectation); - expect(element.props).toEqual(expectation); - expect(element.ref).toBe(ref); - } + expect(() => expect(element.ref).toBe(ref)).toErrorDev( + 'Accessing element.ref was removed in React 19', + {withoutStack: true}, + ); + const expectation = {foo: '56', ref}; + Object.freeze(expectation); + expect(element.props).toEqual(expectation); }); it('coerces the key to a string', () => { const element = ; expect(element.type).toBe(Component); expect(element.key).toBe('12'); - if (gate(flags => flags.enableRefAsProp)) { - expect(element.ref).toBe(null); - } else { - expect(element.ref).toBe(null); - } + expect(element.ref).toBe(null); const expectation = {foo: '56'}; Object.freeze(expectation); expect(element.props).toEqual(expectation); diff --git a/packages/react/src/jsx/ReactJSXElement.js b/packages/react/src/jsx/ReactJSXElement.js index 1652b1e2edecc..de0c682f7fa7e 100644 --- a/packages/react/src/jsx/ReactJSXElement.js +++ b/packages/react/src/jsx/ReactJSXElement.js @@ -20,7 +20,6 @@ import isValidElementType from 'shared/isValidElementType'; import isArray from 'shared/isArray'; import {describeUnknownElementTypeFrameInDEV} from 'shared/ReactComponentStackFrame'; import { - enableRefAsProp, disableStringRefs, disableDefaultPropsExceptForClasses, enableFastJSX, @@ -72,7 +71,6 @@ function getOwner() { } let specialPropKeyWarningShown; -let specialPropRefWarningShown; let didWarnAboutStringRefs; let didWarnAboutElementRef; let didWarnAboutOldJSXRuntime; @@ -82,7 +80,7 @@ if (__DEV__) { didWarnAboutElementRef = {}; } -const enableFastJSXWithStringRefs = enableFastJSX && enableRefAsProp; +const enableFastJSXWithStringRefs = enableFastJSX; const enableFastJSXWithoutStringRefs = enableFastJSXWithStringRefs && disableStringRefs; @@ -161,30 +159,6 @@ function defineKeyPropWarningGetter(props, displayName) { } } -function defineRefPropWarningGetter(props, displayName) { - if (!enableRefAsProp) { - if (__DEV__) { - const warnAboutAccessingRef = function () { - if (!specialPropRefWarningShown) { - specialPropRefWarningShown = true; - console.error( - '%s: `ref` is not a prop. Trying to access it will result ' + - 'in `undefined` being returned. If you need to access the same ' + - 'value within the child component, you should pass it as a different ' + - 'prop. (https://react.dev/link/special-props)', - displayName, - ); - } - }; - warnAboutAccessingRef.isReactWarning = true; - Object.defineProperty(props, 'ref', { - get: warnAboutAccessingRef, - configurable: true, - }); - } - } -} - function elementRefGetterWithDeprecationWarning() { if (__DEV__) { const componentName = getComponentNameFromType(this.type); @@ -227,7 +201,6 @@ function elementRefGetterWithDeprecationWarning() { function ReactElement( type, key, - _ref, self, source, owner, @@ -235,24 +208,19 @@ function ReactElement( debugStack, debugTask, ) { - let ref; - if (enableRefAsProp) { - // When enableRefAsProp is on, ignore whatever was passed as the ref - // argument and treat `props.ref` as the source of truth. The only thing we - // use this for is `element.ref`, which will log a deprecation warning on - // access. In the next release, we can remove `element.ref` as well as the - // `ref` argument. - const refProp = props.ref; + // When enableRefAsProp is on, ignore whatever was passed as the ref + // argument and treat `props.ref` as the source of truth. The only thing we + // use this for is `element.ref`, which will log a deprecation warning on + // access. In the next release, we can remove `element.ref` as well as the + // `ref` argument. + const refProp = props.ref; - // An undefined `element.ref` is coerced to `null` for - // backwards compatibility. - ref = refProp !== undefined ? refProp : null; - } else { - ref = _ref; - } + // An undefined `element.ref` is coerced to `null` for + // backwards compatibility. + const ref = refProp !== undefined ? refProp : null; let element; - if (__DEV__ && enableRefAsProp) { + if (__DEV__) { // In dev, make `ref` a non-enumerable property with a warning. It's non- // enumerable so that test matchers and serializers don't access it and // trigger the warning. @@ -382,7 +350,6 @@ function ReactElement( */ export function jsxProd(type, config, maybeKey) { let key = null; - let ref = null; // Currently, key can be spread in as a prop. This causes a potential // issue if key is also explicitly declared (ie.
@@ -404,15 +371,6 @@ export function jsxProd(type, config, maybeKey) { key = '' + config.key; } - if (hasValidRef(config)) { - if (!enableRefAsProp) { - ref = config.ref; - if (!disableStringRefs) { - ref = coerceStringRef(ref, getOwner(), type); - } - } - } - let props; if ( (enableFastJSXWithoutStringRefs || @@ -436,8 +394,8 @@ export function jsxProd(type, config, maybeKey) { props = {}; for (const propName in config) { // Skip over reserved prop names - if (propName !== 'key' && (enableRefAsProp || propName !== 'ref')) { - if (enableRefAsProp && !disableStringRefs && propName === 'ref') { + if (propName !== 'key') { + if (!disableStringRefs && propName === 'ref') { props.ref = coerceStringRef(config[propName], getOwner(), type); } else { props[propName] = config[propName]; @@ -461,7 +419,6 @@ export function jsxProd(type, config, maybeKey) { return ReactElement( type, key, - ref, undefined, undefined, getOwner(), @@ -664,7 +621,6 @@ function jsxDEVImpl( } let key = null; - let ref = null; // Currently, key can be spread in as a prop. This causes a potential // issue if key is also explicitly declared (ie.
@@ -686,14 +642,8 @@ function jsxDEVImpl( key = '' + config.key; } - if (hasValidRef(config)) { - if (!enableRefAsProp) { - ref = config.ref; - if (!disableStringRefs) { - ref = coerceStringRef(ref, getOwner(), type); - } - } - if (!disableStringRefs) { + if (!disableStringRefs) { + if (hasValidRef(config)) { warnIfStringRefCannotBeAutoConverted(config, self); } } @@ -721,8 +671,8 @@ function jsxDEVImpl( props = {}; for (const propName in config) { // Skip over reserved prop names - if (propName !== 'key' && (enableRefAsProp || propName !== 'ref')) { - if (enableRefAsProp && !disableStringRefs && propName === 'ref') { + if (propName !== 'key') { + if (!disableStringRefs && propName === 'ref') { props.ref = coerceStringRef(config[propName], getOwner(), type); } else { props[propName] = config[propName]; @@ -743,23 +693,17 @@ function jsxDEVImpl( } } - if (key || (!enableRefAsProp && ref)) { + if (key) { const displayName = typeof type === 'function' ? type.displayName || type.name || 'Unknown' : type; - if (key) { - defineKeyPropWarningGetter(props, displayName); - } - if (!enableRefAsProp && ref) { - defineRefPropWarningGetter(props, displayName); - } + defineKeyPropWarningGetter(props, displayName); } return ReactElement( type, key, - ref, self, source, getOwner(), @@ -840,7 +784,6 @@ export function createElement(type, config, children) { const props = {}; let key = null; - let ref = null; if (config != null) { if (__DEV__) { @@ -863,15 +806,8 @@ export function createElement(type, config, children) { } } - if (hasValidRef(config)) { - if (!enableRefAsProp) { - ref = config.ref; - if (!disableStringRefs) { - ref = coerceStringRef(ref, getOwner(), type); - } - } - - if (__DEV__ && !disableStringRefs) { + if (__DEV__ && !disableStringRefs) { + if (hasValidRef(config)) { warnIfStringRefCannotBeAutoConverted(config, config.__self); } } @@ -888,7 +824,6 @@ export function createElement(type, config, children) { hasOwnProperty.call(config, propName) && // Skip over reserved prop names propName !== 'key' && - (enableRefAsProp || propName !== 'ref') && // Even though we don't use these anymore in the runtime, we don't want // them to appear as props, so in createElement we filter them out. // We don't have to do this in the jsx() runtime because the jsx() @@ -896,7 +831,7 @@ export function createElement(type, config, children) { propName !== '__self' && propName !== '__source' ) { - if (enableRefAsProp && !disableStringRefs && propName === 'ref') { + if (!disableStringRefs && propName === 'ref') { props.ref = coerceStringRef(config[propName], getOwner(), type); } else { props[propName] = config[propName]; @@ -933,24 +868,18 @@ export function createElement(type, config, children) { } } if (__DEV__) { - if (key || (!enableRefAsProp && ref)) { + if (key) { const displayName = typeof type === 'function' ? type.displayName || type.name || 'Unknown' : type; - if (key) { - defineKeyPropWarningGetter(props, displayName); - } - if (!enableRefAsProp && ref) { - defineRefPropWarningGetter(props, displayName); - } + defineKeyPropWarningGetter(props, displayName); } } return ReactElement( type, key, - ref, undefined, undefined, getOwner(), @@ -964,9 +893,6 @@ export function cloneAndReplaceKey(oldElement, newKey) { const clonedElement = ReactElement( oldElement.type, newKey, - // When enableRefAsProp is on, this argument is ignored. This check only - // exists to avoid the `ref` access warning. - enableRefAsProp ? null : oldElement.ref, undefined, undefined, !__DEV__ && disableStringRefs ? undefined : oldElement._owner, @@ -999,7 +925,6 @@ export function cloneElement(element, config, children) { // Reserved names are extracted let key = element.key; - let ref = enableRefAsProp ? null : element.ref; // Owner will be preserved, unless ref is overridden let owner = !__DEV__ && disableStringRefs ? undefined : element._owner; @@ -1007,13 +932,6 @@ export function cloneElement(element, config, children) { if (config != null) { if (hasValidRef(config)) { owner = __DEV__ || !disableStringRefs ? getOwner() : undefined; - if (!enableRefAsProp) { - // Silently steal the ref from the parent. - ref = config.ref; - if (!disableStringRefs) { - ref = coerceStringRef(ref, owner, element.type); - } - } } if (hasValidKey(config)) { if (__DEV__) { @@ -1036,7 +954,6 @@ export function cloneElement(element, config, children) { hasOwnProperty.call(config, propName) && // Skip over reserved prop names propName !== 'key' && - (enableRefAsProp || propName !== 'ref') && // ...and maybe these, too, though we currently rely on them for // warnings and debug information in dev. Need to decide if we're OK // with dropping them. In the jsx() runtime it's not an issue because @@ -1048,7 +965,7 @@ export function cloneElement(element, config, children) { // Undefined `ref` is ignored by cloneElement. We treat it the same as // if the property were missing. This is mostly for // backwards compatibility. - !(enableRefAsProp && propName === 'ref' && config.ref === undefined) + !(propName === 'ref' && config.ref === undefined) ) { if ( !disableDefaultPropsExceptForClasses && @@ -1058,7 +975,7 @@ export function cloneElement(element, config, children) { // Resolve default props props[propName] = defaultProps[propName]; } else { - if (enableRefAsProp && !disableStringRefs && propName === 'ref') { + if (!disableStringRefs && propName === 'ref') { props.ref = coerceStringRef(config[propName], owner, element.type); } else { props[propName] = config[propName]; @@ -1084,7 +1001,6 @@ export function cloneElement(element, config, children) { const clonedElement = ReactElement( element.type, key, - ref, undefined, undefined, owner, diff --git a/packages/shared/ReactFeatureFlags.js b/packages/shared/ReactFeatureFlags.js index 3c2089cb19c13..cf89064979770 100644 --- a/packages/shared/ReactFeatureFlags.js +++ b/packages/shared/ReactFeatureFlags.js @@ -193,7 +193,6 @@ export const enableInfiniteRenderLoopDetection = true; // Passes `ref` as a normal prop instead of stripping it from the props object // during element creation. -export const enableRefAsProp = true; export const disableStringRefs = true; export const enableFastJSX = true; diff --git a/packages/shared/forks/ReactFeatureFlags.native-fb.js b/packages/shared/forks/ReactFeatureFlags.native-fb.js index b37f2f4fa0c14..a6a00c2de6309 100644 --- a/packages/shared/forks/ReactFeatureFlags.native-fb.js +++ b/packages/shared/forks/ReactFeatureFlags.native-fb.js @@ -69,7 +69,6 @@ export const enableProfilerCommitHooks = __PROFILE__; export const enableProfilerNestedUpdatePhase = __PROFILE__; export const enableProfilerTimer = __PROFILE__; export const enableReactTestRendererWarning = false; -export const enableRefAsProp = true; export const enableRenderableContext = true; export const enableRetryLaneExpiration = false; export const enableSchedulingProfiler = __PROFILE__; diff --git a/packages/shared/forks/ReactFeatureFlags.native-oss.js b/packages/shared/forks/ReactFeatureFlags.native-oss.js index 3ef19e4b127e7..175ae0493c6ee 100644 --- a/packages/shared/forks/ReactFeatureFlags.native-oss.js +++ b/packages/shared/forks/ReactFeatureFlags.native-oss.js @@ -60,7 +60,6 @@ export const enableObjectFiber = false; export const enableOwnerStacks = false; export const enablePostpone = false; export const enableReactTestRendererWarning = false; -export const enableRefAsProp = true; export const enableRenderableContext = true; export const enableRetryLaneExpiration = false; export const enableSchedulingProfiler = __PROFILE__; diff --git a/packages/shared/forks/ReactFeatureFlags.test-renderer.js b/packages/shared/forks/ReactFeatureFlags.test-renderer.js index 5b01abdb496bf..01685f9f8275e 100644 --- a/packages/shared/forks/ReactFeatureFlags.test-renderer.js +++ b/packages/shared/forks/ReactFeatureFlags.test-renderer.js @@ -87,7 +87,6 @@ export const enableShallowPropDiffing = false; // We really need to get rid of this whole module. Any test renderer specific // flags should be handled by the Fiber config. // const __NEXT_MAJOR__ = __EXPERIMENTAL__; -export const enableRefAsProp = true; export const disableStringRefs = true; export const enableFastJSX = true; export const disableLegacyMode = true; diff --git a/packages/shared/forks/ReactFeatureFlags.test-renderer.native-fb.js b/packages/shared/forks/ReactFeatureFlags.test-renderer.native-fb.js index ebb8964a5b741..6f640b7c82a6b 100644 --- a/packages/shared/forks/ReactFeatureFlags.test-renderer.native-fb.js +++ b/packages/shared/forks/ReactFeatureFlags.test-renderer.native-fb.js @@ -55,7 +55,6 @@ export const enableProfilerCommitHooks = __PROFILE__; export const enableProfilerNestedUpdatePhase = __PROFILE__; export const enableProfilerTimer = __PROFILE__; export const enableReactTestRendererWarning = false; -export const enableRefAsProp = true; export const enableRenderableContext = true; export const enableRetryLaneExpiration = false; export const enableSchedulingProfiler = __PROFILE__; diff --git a/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js b/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js index 026c2be4f8c67..f366831b03dd9 100644 --- a/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js +++ b/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js @@ -79,7 +79,6 @@ export const disableClientCache = true; export const enableServerComponentLogs = true; export const enableInfiniteRenderLoopDetection = false; -export const enableRefAsProp = true; export const disableStringRefs = false; export const enableFastJSX = false; diff --git a/packages/shared/forks/ReactFeatureFlags.www.js b/packages/shared/forks/ReactFeatureFlags.www.js index 3671f40ad8d31..189eb24592871 100644 --- a/packages/shared/forks/ReactFeatureFlags.www.js +++ b/packages/shared/forks/ReactFeatureFlags.www.js @@ -93,8 +93,6 @@ export const enableLegacyHidden = true; export const enableComponentStackLocations = true; -export const enableRefAsProp = true; - export const disableTextareaChildren = __EXPERIMENTAL__; export const allowConcurrentByDefault = true;