LEARN · DEBUGGING GUIDE

Diagnosing `ref.current` Is Null in React

If your React ref's `current` property is unexpectedly null, you're not alone. Here are the concrete reasons—and fixes—you won't find in the docs.

IntermediateReact bugs4 min read

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.

( 01 )Fast diagnosis

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).
( 02 )Where to look

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
( 03 )Common root causes

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
( 04 )Fix patterns

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`
( 05 )How to verify

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
( 06 )Mistakes to avoid

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`
( 07 )War story

Ref Null When Focusing Input After Modal Appears

Frontend EngineerReact 17, React Bootstrap Modal, Jest, Chrome DevTools

Timeline

  1. 13:58Deployed feature requiring modal to auto-focus input
  2. 14:03Sentry reports 'Cannot read property focus of null'
  3. 14:09DevTools log shows `inputRef.current` is null in `useEffect`
  4. 14:13Realize ref not attached since input is rendered conditionally
  5. 14:19Move focus logic into effect that depends on modal open state
  6. 14:22Bug resolved locally—input auto-focuses as modal opens
  7. 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.

( 08 )Timing of Ref Assignment in React

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.

( 09 )Forwarding Refs to Custom Components

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} />);`

( 10 )Conditional Rendering: The Hidden Danger

If you conditionally render the ref'd node, e.g., `{isOpen && <input ref={inputRef} />}`, the ref will be null when `isOpen` is false. Any code relying on `ref.current` outside of this condition will break.

Always place logic depending on the ref in a useEffect with proper dependencies, checking `if (ref.current)`, and ensure the node exists in the render branch.

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.