Suggest an editImprove this articleRefine the answer for “How do you type useRef()?”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)`useRef` creates a **ref object** (`{ current: ... }`) that React keeps across renders, typed as `function useRef<T>(initialValue: T): MutableRefObject<T>`. **Key point:** if the ref starts out as `null` (for example, a DOM reference), the type must be specified explicitly, for example `useRef<HTMLInputElement | null>(null)`.Shown above the full answer for quick recall.Answer (EN)Image## 1. What `useRef` does `useRef` creates a **ref object** (`{ current: ... }`), which React keeps across renders. The type signature: ```javascript function useRef<T>(initialValue: T): MutableRefObject<T>; ``` --- ## 2. Basic typing ```javascript const countRef = useRef<number>(0); countRef.current++; // current is a number ``` TypeScript knows that `countRef.current` is `number`. If you pass an initial value, TS infers the type automatically: ```javascript const flagRef = useRef(false); // inferred: MutableRefObject<boolean> ``` --- ## 3. If it starts out as `null` (DOM or lazy references) When a `ref` starts out as `null`, you must specify the type explicitly: ```javascript // A reference to a DOM element const inputRef = useRef<HTMLInputElement | null>(null); ``` Here `current` can be `null` before mounting. When using it: ```javascript inputRef.current?.focus(); ``` Safe: `?.` guards against `null`. --- ## 4. Passing a `ref` into an element ```javascript export function Form() { const inputRef = useRef<HTMLInputElement | null>(null); return <input ref={inputRef} type="text" />; } ``` TypeScript already knows that `inputRef.current` is `HTMLInputElement | null`. > For different elements: > > - `HTMLDivElement` > - `HTMLButtonElement` > - `HTMLFormElement` > - `HTMLTextAreaElement` > - `HTMLAnchorElement` > and so on. --- ## 5. When you only need to store a value (not DOM) ```javascript const intervalId = useRef<number | null>(null); useEffect(() => { intervalId.current = window.setInterval(() => console.log('tick'), 1000); return () => clearInterval(intervalId.current!); }, []); ``` Useful for storing mutable variables without a re-render. --- ## 6. An example with `forwardRef` ```javascript type InputProps = React.ComponentProps<"input">; const Input = React.forwardRef<HTMLInputElement, InputProps>((props, ref) => { return <input ref={ref} {...props} />; }); // Usage const inputRef = useRef<HTMLInputElement>(null); <Input ref={inputRef} />; ``` `forwardRef` takes two type parameters: ```javascript React.forwardRef<ElementType, PropsType>() ``` --- ## 7. When you need `useRef<T | null>(null)` vs `useRef<T>(...)` | Scenario | Type | | --- | --- | | A DOM element (mounts later) | `useRef<T \| null>(null)` | | A simple variable (number, object, etc.) | `useRef<T>(value)` | | Lazy initialization | `useRef<T \| null>(null)` | --- ## 8. A "readonly ref" (an immutable reference) If the reference **will not be changed manually**, you can use `React.RefObject<T>`: ```javascript const divRef: React.RefObject<HTMLDivElement> = useRef(null); ``` `RefObject` = `{ readonly current: T | null }` Used when you just pass the `ref` along without modifying it. --- ## 9. An example: click outside an element ```javascript function Dropdown() { const menuRef = useRef<HTMLDivElement | null>(null); useEffect(() => { function handleClick(e: MouseEvent) { if (!menuRef.current?.contains(e.target as Node)) { console.log("Clicked outside"); } } document.addEventListener("click", handleClick); return () => document.removeEventListener("click", handleClick); }, []); return <div ref={menuRef}>Menu</div>; } ``` `menuRef.current` is typed correctly. `contains()` is called safely. --- ## Summary | Scenario | Typing | | --- | --- | | A simple ref variable | `useRef<number>(0)` | | A DOM ref | `useRef<HTMLDivElement \| null>(null)` | | A ref on `<input>` | `useRef<HTMLInputElement \| null>(null)` | | A ref for a timer / id | `useRef<number \| null>(null)` | | Read-only | `React.RefObject<T>` | | With `forwardRef` | `React.forwardRef<T, Props>()` | --- > In short: > > - Always add `| null` if the `ref` is for the DOM. > - Do not write `any`. Use the exact element type (`HTMLDivElement`, `HTMLInputElement`, etc.). > - To store "mutable" data without a re-render, use `useRef<T>()`. > - For references between components, use `forwardRef()` with a generic.For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.