An input component auto-focusing on mount. Author wrote `inputRef.focus()`. TypeScript would have caught it but the file had `any` types. Runtime: TypeError.
The vulnerable diff
// components/SearchInput.tsx
export function SearchInput() {
const inputRef = useRef<HTMLInputElement>(null);
useEffect(() => {
// BUG: inputRef is the ref object, not the DOM node
inputRef.focus(); // TypeError: inputRef.focus is not a function
}, []);
return <input ref={inputRef} />;
}What is wrong
`useRef<T>(initial)` returns a stable object `{ current: T | null }`. The DOM node is stored in `.current` after React attaches the ref. Methods on the node are reached via `.current.focus()`. Calling `.focus()` on the ref object itself is a no-op because ref objects do not have that method — TypeError at runtime.
The attack
Repro: open the page in dev, look at the console. TypeError on mount.
# Browser console:
TypeError: inputRef.focus is not a function
at SearchInput.useEffect (SearchInput.tsx:7:3)Component does not mount, surrounding UI may still work depending on error boundary placement.
Mesrai's review comment
mesraipilot · Bot · reviewed 20 sec ago
[mesrai] [code-review] [Language] [React] [low]
`useRef` returns `{ current: T | null }`, not the value directly.
Access the DOM node via `.current`:
inputRef.current?.focus();
The optional chaining handles the null case (ref not yet attached
or component unmounted).
If you typed the ref as `useRef<HTMLInputElement>(null)`, TypeScript
should have caught this. Check that `any` hasn't leaked into the
component types.The fix
// components/SearchInput.tsx — fixed
export function SearchInput() {
const inputRef = useRef<HTMLInputElement>(null);
useEffect(() => {
inputRef.current?.focus();
}, []);
return <input ref={inputRef} />;
}`.current?.focus()` reads the node and safely no-ops if null. Standard React-with-DOM pattern.
Why human review missed it
The bug is junior-grade — but it shows up because TypeScript types were widened to `any` somewhere, or the team is still using JS. Mesrai catches the pattern by flagging method calls directly on a `useRef` return value.
Related rules + further reading
Mesrai rule pack: language/react-ref-current — flags method calls on useRef return without .current.
React docs: Manipulating the DOM with Refs.
TypeScript catches if types are strict — but the bug recurs when they're not.
Takeaway
.current is mandatory. The ref is the box; the value is inside. Mesrai catches the missing access.