Ref as Plain Prop & useRef Cleanup Lifecycle Functions
- Last updated
- Prerequisites:
- useRef basics
- DOM element references
- react
- ref
- forwardRef
- cleanup
- dom
- react-19
Read at your depth
The practical view
In React 19, `forwardRef` is deprecated. You can pass `ref` as a standard prop directly into functional components: `function MyInput({ ref, ...props })`. Additionally, callback refs now support **cleanup functions**: `ref={(node) => { attach(node); return () => detach(node); }}`. The returned cleanup function executes whenever the node is removed from the DOM, eliminating manual `null` checks.
The same idea in other frameworks
`ref={(el) => { observer.observe(el); return () => observer.disconnect(); }}``ElementRef` with `ngOnDestroy` or custom directives.Template refs with `onMounted` / `onUnmounted` teardown.`use:action` directive with `destroy()` cleanup return.Legacy vs modern
forwardRef + Null Checking vs Direct Ref Prop + Cleanup Function
`forwardRef` is boilerplate-heavy and `null` checking is error-prone; React 19 enables plain ref props and automatic teardown returns.
const Input = forwardRef((props, ref) => <input ref={ref} />); // ❌ Deprecated forwardReffunction Input({ ref, ...props }) { return <input ref={ref} />; } // ✅ NEWInterview gotchas
Context
Interviewers test your attention to subtle arrow function return bugs in React 19.
The mechanical answer
If a callback ref returns a non-function value (e.g. an implicit arrow function return like `ref={el => map.set(id, el)}` which returns `Map`), React 19 will throw a runtime error warning that ref callbacks must either return a cleanup function or `undefined`.
Trap
Avoid writing concise arrow functions with single-expression returns if they return a value. Wrap them in braces: `ref={el => { map.set(id, el); }}`.
Context
Tests knowledge of migration paths and backward compatibility.
The mechanical answer
`forwardRef` is deprecated in React 19 and will eventually be removed in future major versions. Plain functional components accept `ref` directly as a prop. Existing `forwardRef` calls still work for backward compatibility but emit deprecation warnings in strict mode.
Trap
Do not wrap new React 19 components in `forwardRef`.