Bug description
PopChild reads children.props?.ref unconditionally on every render, regardless of whether mode=\"popLayout\" is active (i.e. whether pop is true). In React 18.3, creating a React element with a ref prop causes React to define a warning getter on element.props.ref via defineRefPropWarningGetter. When anything accesses that getter, it fires:
Warning: [object Object]: `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.
The [object Object] display name occurs because motion.div (and other motion.* elements) are forwardRef objects — plain JS objects with $$typeof: REACT_FORWARD_REF_TYPE rather than functions — so typeof type !== 'function', and React's element validator sets displayName = type (the raw object), which String()-ifies to [object Object].
Why it fires
In PopChild.mjs:
// Lines 56–61 (framer-motion@12.38.0)
const childRef = children.props?.ref ??
children?.ref;
const composedRef = useComposedRefs(ref, childRef);
childRef and composedRef are only ever used when pop !== false:
: React.cloneElement(children, { ref: composedRef })
When pop === false (the default for mode="sync" and mode="wait"), the ref is computed and composed but never passed anywhere. However, the unconditional children.props?.ref read still triggers the React 18.3 warning getter for any motion.* element that was created with a ref prop.
Minimal repro
Any AnimatePresence without mode="popLayout" that wraps a motion.div with a ref:
const ref = useRef(null)
<AnimatePresence>
{isVisible && (
<motion.div key="content" ref={ref} exit={{ opacity: 0 }}>
Hello
</motion.div>
)}
</AnimatePresence>
Console output in React 18.3:
Warning: [object Object]: `ref` is not a prop.
Stack trace points to PopChild → PresenceChild → AnimatePresence.
Proposed fix
Only access children.props?.ref when pop !== false, since the ref is only needed in the cloneElement branch:
-const childRef = children.props?.ref ??
- children?.ref;
+const childRef = pop !== false
+ ? (children.props?.ref ?? children?.ref)
+ : undefined;
const composedRef = useComposedRefs(ref, childRef);
Environment
motion / framer-motion: 12.38.0 (also reproducible on latest 12.40.0 — main branch still has the unconditional read)
- React:
18.3.1
- The warning only fires once globally per app run due to
specialPropRefWarningShown = true, but it appears in every test run that renders a modal/sheet/panel backed by AnimatePresence.
Notes
- The CHANGELOG mentions fixes for
popLayout + React 19 ref access (v12.23.16, v12.24.5), but this is a separate issue: it affects non-popLayout mode under React 18.3, not React 19.
- We are currently working around this with a pnpm patch on our end.
Bug description
PopChildreadschildren.props?.refunconditionally on every render, regardless of whethermode=\"popLayout\"is active (i.e. whetherpopistrue). In React 18.3, creating a React element with arefprop causes React to define a warning getter onelement.props.refviadefineRefPropWarningGetter. When anything accesses that getter, it fires:The
[object Object]display name occurs becausemotion.div(and othermotion.*elements) areforwardRefobjects — plain JS objects with$$typeof: REACT_FORWARD_REF_TYPErather than functions — sotypeof type !== 'function', and React's element validator setsdisplayName = type(the raw object), whichString()-ifies to[object Object].Why it fires
In
PopChild.mjs:childRefandcomposedRefare only ever used whenpop !== false:When
pop === false(the default formode="sync"andmode="wait"), the ref is computed and composed but never passed anywhere. However, the unconditionalchildren.props?.refread still triggers the React 18.3 warning getter for anymotion.*element that was created with arefprop.Minimal repro
Any
AnimatePresencewithoutmode="popLayout"that wraps amotion.divwith aref:Console output in React 18.3:
Stack trace points to
PopChild→PresenceChild→AnimatePresence.Proposed fix
Only access
children.props?.refwhenpop !== false, since the ref is only needed in thecloneElementbranch:Environment
motion/framer-motion:12.38.0(also reproducible on latest12.40.0—mainbranch still has the unconditional read)18.3.1specialPropRefWarningShown = true, but it appears in every test run that renders a modal/sheet/panel backed byAnimatePresence.Notes
popLayout+ React 19 ref access (v12.23.16, v12.24.5), but this is a separate issue: it affects non-popLayout mode under React 18.3, not React 19.