Skip to content

Commit

Permalink
Refine getElementRef
Browse files Browse the repository at this point in the history
  • Loading branch information
Vlad Moroz committed Jun 4, 2024
1 parent ceb0e7c commit e890cc1
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 20 deletions.
24 changes: 14 additions & 10 deletions packages/react/presence/src/Presence.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -144,22 +144,26 @@ function getAnimationName(styles?: CSSStyleDeclaration) {
}

// Before React 19 accessing `element.props.ref` will throw a warning and suggest using `element.ref`
// After React 19 accessing `element.ref` does the opposite
// After React 19 accessing `element.ref` does the opposite.
// https://github.com/facebook/react/pull/28348
//
// Access the ref using the method that doesn't yield a warning
// Access the ref using the method that doesn't yield a warning.
function getElementRef(element: React.ReactElement) {
// In DEV only:
// Pre React 19 there's a getter on `element.props.ref` that throws a warning when attempting to access it.
// This is safe to rely on. (As in... obviously, old React versions won't change).
// https://github.com/facebook/react/blob/408258268edb5acdfdbf77bc6e0b0dc6396c0e6f/packages/react/src/jsx/ReactJSXElement.js#L89-L99
const getter = Object.getOwnPropertyDescriptor(element.props, 'ref')?.get;
const hasPropWarning = getter && 'isReactWarning' in getter && getter.isReactWarning;
if (hasPropWarning) {
// React <=18 in DEV
let getter = Object.getOwnPropertyDescriptor(element.props, 'ref')?.get;
let mayWarn = getter && 'isReactWarning' in getter && getter.isReactWarning;
if (mayWarn) {
return (element as any).ref;
}

// React >=19 || React <19 not in DEV
// React 19 in DEV
getter = Object.getOwnPropertyDescriptor(element, 'ref')?.get;
mayWarn = getter && 'isReactWarning' in getter && getter.isReactWarning;
if (mayWarn) {
return element.props.ref;
}

// Not DEV
return element.props.ref || (element as any).ref;
}

Expand Down
24 changes: 14 additions & 10 deletions packages/react/slot/src/Slot.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -124,22 +124,26 @@ function mergeProps(slotProps: AnyProps, childProps: AnyProps) {
}

// Before React 19 accessing `element.props.ref` will throw a warning and suggest using `element.ref`
// After React 19 accessing `element.ref` does the opposite
// After React 19 accessing `element.ref` does the opposite.
// https://github.com/facebook/react/pull/28348
//
// Access the ref using the method that doesn't yield a warning
// Access the ref using the method that doesn't yield a warning.
function getElementRef(element: React.ReactElement) {
// In DEV only:
// Pre React 19 there's a getter on `element.props.ref` that throws a warning when attempting to access it.
// This is safe to rely on. (As in... obviously, old React versions won't change).
// https://github.com/facebook/react/blob/408258268edb5acdfdbf77bc6e0b0dc6396c0e6f/packages/react/src/jsx/ReactJSXElement.js#L89-L99
const getter = Object.getOwnPropertyDescriptor(element.props, 'ref')?.get;
const hasPropWarning = getter && 'isReactWarning' in getter && getter.isReactWarning;
if (hasPropWarning) {
// React <=18 in DEV
let getter = Object.getOwnPropertyDescriptor(element.props, 'ref')?.get;
let mayWarn = getter && 'isReactWarning' in getter && getter.isReactWarning;
if (mayWarn) {
return (element as any).ref;
}

// React >=19 || React <19 not in DEV
// React 19 in DEV
getter = Object.getOwnPropertyDescriptor(element, 'ref')?.get;
mayWarn = getter && 'isReactWarning' in getter && getter.isReactWarning;
if (mayWarn) {
return element.props.ref;
}

// Not DEV
return element.props.ref || (element as any).ref;
}

Expand Down

0 comments on commit e890cc1

Please sign in to comment.