diff --git a/src/ref.ts b/src/ref.ts index fd9513b9..06fd5741 100644 --- a/src/ref.ts +++ b/src/ref.ts @@ -90,17 +90,19 @@ export const supportNodeRef = ( /** * In React 19. `ref` is not a property from node. * But a property from `props.ref`. - * To check if `props.ref` exist or fallback to `ref`. + * In < React 19, `ref` lives on the element itself (`element.ref`). */ export const getNodeRef: ( node: React.ReactNode, ) => React.Ref | null = node => { if (node && isReactElement(node)) { const ele = node as any; - - // Source from: - // https://github.com/mui/material-ui/blob/master/packages/mui-utils/src/getReactNodeRef/getReactNodeRef.ts - return ele.props.propertyIsEnumerable('ref') ? ele.props.ref : ele.ref; + // React 19: `ref` is a regular prop and reading `element.ref` triggers a + // deprecation warning, even when the prop is absent. Branch on the React + // major version to avoid touching `element.ref` on React 19+. + return ReactMajorVersion >= 19 + ? (ele.props.ref ?? null) + : (ele.ref ?? null); } return null; }; diff --git a/tests/ref-19.test.tsx b/tests/ref-19.test.tsx index b51d2ce4..906577f6 100644 --- a/tests/ref-19.test.tsx +++ b/tests/ref-19.test.tsx @@ -44,6 +44,16 @@ describe('ref: React 19', () => { expect(errSpy).not.toHaveBeenCalled(); }); + it('getNodeRef on element without ref does not access element.ref', () => { + // Regression: previous propertyIsEnumerable('ref') check fell back to + // `element.ref` for elements rendered without an explicit ref prop, which + // triggers React 19's "Accessing element.ref was removed" warning. + const node =
; + + expect(getNodeRef(node)).toBeNull(); + expect(errSpy).not.toHaveBeenCalled(); + }); + it('useComposeRef', () => { const Demo: React.FC = ({ children }) => { const ref = React.useRef(null);