What this usually means
React refs only attach to actual DOM nodes or class components. If `ref.current` is null, either the ref hasn't been attached yet (lifecycle issue), it's not attached to a valid node, or the component unmounted. This also happens with StrictMode's double rendering, conditional rendering that skips the DOM node, or assigning refs to function components, which is unsupported out-of-the-box. Unintentional remounts and ref timing bugs are common. Async effects relying on refs before mount are a classic pitfall.
The first ten minutes — establish facts before touching code.
- 1Console.log `ref.current` after your effect or callback—confirm when it's null vs set.
- 2Check if you're passing the ref to a DOM node or a function component; the latter won't attach.
- 3Wrap your code in `useEffect(() => { ... }, [])`; does `ref.current` stay null?
- 4Enable React StrictMode—does the failure only happen on the second render?
- 5Verify the DOM node isn't conditionally rendered (e.g., `{show && <input ref={myRef} />}` when `show` is false).
The specific files, logs, configs, and dashboards that usually own this bug.
- searchComponent render methods where `ref` props are assigned
- searchPlaces using `ref.current` (e.g., focus, scrollTo, measure calls)
- searchCustom hook files (look for `useRef`, `useImperativeHandle` use)
- searchsrc/index.js or App.js for React.StrictMode usage
- searchComponent tree or React DevTools to inspect ref assignments
- searchAny conditional rendering logic controlling when the ref'd node exists
Practical causes, not theory. These are the things you will actually find.
- warningTrying to attach a ref to a function component without `forwardRef`
- warningCalling `ref.current` before the element is mounted (even in useEffect)
- warningNode is conditionally rendered and absent when ref is needed
- warningStrictMode double-mount causing ref to be reset during development
- warningRelying on `ref.current` in async handlers after unmount
- warningMultiple refs pointing to the same DOM node, causing overwrites
Concrete fix directions. Pick the one that matches your root cause.
- buildUse `React.forwardRef` when passing refs to custom components
- buildCheck for `ref.current` nullity before accessing properties or methods
- buildMove logic using `ref.current` into a `useEffect` that depends on the DOM node
- buildGuard code with `if (ref.current)` before using
- buildRevisit conditional rendering so the DOM node always exists when needed
- buildAvoid storing refs in state—use `useRef` and always access `.current`
A fix you cannot prove is a guess. Close the loop.
- verifiedAdd temporary `console.log(ref.current)` for every relevant render and effect
- verifiedTest under React StrictMode (`<React.StrictMode>` in index.js) and without it
- verifiedClick through all UI states that could hide/show the node and confirm ref assignment
- verifiedUse React DevTools to inspect live ref attachment
- verifiedWrite a Cypress/Playwright test to assert UI focus or direct DOM effects
Things that make this bug worse or harder to find.
- warningAssuming `ref.current` is set immediately after render in function components
- warningPassing refs to function components without using `forwardRef`
- warningUsing refs in async callbacks after the component has unmounted
- warningIgnoring conditional rendering that removes the ref'd node
- warningRelying on `ref.current` in the body of the render function
- warningDeclaring refs inside component logic instead of using `useRef`
Ref Null When Focusing Input After Modal Appears
Timeline
- 13:58Deployed feature requiring modal to auto-focus input
- 14:03Sentry reports 'Cannot read property focus of null'
- 14:09DevTools log shows `inputRef.current` is null in `useEffect`
- 14:13Realize ref not attached since input is rendered conditionally
- 14:19Move focus logic into effect that depends on modal open state
- 14:22Bug resolved locally—input auto-focuses as modal opens
- 14:33Write regression test for modal focus with Jest/react-testing-library
I shipped a modal with an auto-focus feature on the main input, using a `useRef` to grab the DOM node. During manual QA, everything worked, but in production, Sentry started reporting 'Cannot read property focus of null'.
Using Chrome DevTools, I added console logs in both the render and useEffect hooks. I realized that when the modal wasn't open, the input did not exist in the DOM, so the ref's current was null when my effect fired.
After moving my focus logic into a `useEffect` whose dependency included the modal's open state, the ref assignment aligned with the node's presence. The fix passed all local tests, and I added a regression check to prevent recurrence.
Root cause
Input's DOM node (and ref) did not exist when auto-focus logic ran due to conditional rendering in a modal.
The fix
Delayed focus logic until after the input was rendered by tying the focus effect to the modal's open state.
The lesson
Never assume the ref's DOM node exists unless you control when the effect fires—always tie side effects to actual render state.
In function components, refs are assigned after the DOM node mounts, which means `ref.current` is null during the initial render. Accessing it in effects or event handlers before the node exists is a frequent source of this error.
React's StrictMode exacerbates timing by mounting and unmounting components twice in development. Effects might see a valid `ref.current` on the first mount, then null again after unmount, catching developers off-guard.
Passing a ref prop directly to a function component won't attach to the DOM node. Instead, React sets `ref.current` to null, since function components don't expose instances.
Use `React.forwardRef` in custom components to enable ref forwarding. For example: `const FancyInput = React.forwardRef((props, ref) => <input ref={ref} {...props} />);`
Frequently asked questions
Why is my ref null even inside useEffect?
If the DOM node hasn't rendered yet due to conditional logic or StrictMode remounting, your ref will still be null in useEffect. Make sure your effect's dependencies include whatever controls the node's presence.
Can I use refs with function components?
Not directly. Use React.forwardRef to explicitly allow ref passing to function components. Otherwise, ref.current will always be null.
Does React StrictMode affect refs?
Yes, StrictMode double-mounts components in development, causing refs to be set and then torn down rapidly—surfacing timing bugs you might otherwise miss.
How do I know if conditional rendering is the issue?
Log or breakpoint your render tree and check if the ref's target node actually exists when you access it. Inconsistent presence usually means a conditional render problem.