How to fix React Hook useRef has a missing dependency: in React

ReactBEGINNERLOWUpdated Dec 9, 2025ยท 117 views

ESLint's exhaustive-deps rule warns when a ref created with useRef is used inside useEffect but not listed in the dependency array. However, refs are intentionally stable and should typically not be included as dependencies since mutating ref.current does not trigger re-renders. Understanding when to include or exclude refs prevents confusion and maintains proper hook behavior.

Quick fix

Fixes React Hook useRef has a missing dependency:

function MyComponent() {
  const countRef = useRef(0);
  
  useEffect(() => {
    // Using countRef here - should it be a dependency?
    countRef.current += 1;
    console.log('Render count:', countRef.current);
  });
  
  // countRef object never changes, so no need to list it as a dependency
}
  1. Understand that refs are intentionally stable and typically should not be dependencies
  2. Either include the ref in the dependency array or suppress the warning
  3. If you need to react to ref.current changes, use useState instead
  4. For DOM element refs, access them safely without dependencies
react โ€” error
function MyComponent() {
const countRef = useRef(0);
useEffect(() => {
// Using countRef here - should it be a dependency?
countRef.current += 1;
console.log('Render count:', countRef.current);
});
// countRef object never changes, so no need to list it as a dependency
}
React Hook useRef has a missing dependency:

What this error means

This ESLint warning comes from the react-hooks/exhaustive-deps rule, which validates that all values used inside useEffect, useCallback, useMemo, and other hooks are properly listed in their dependency arrays. The rule helps prevent stale closure bugs by ensuring hooks re-run when their dependencies change. However, when it flags useRef, it's often a false positive or indicates a misunderstanding of how refs work. Refs created by useRef return a stable object that persists across renders - the ref object itself never changes, only its .current property can be mutated. Since mutating ref.current does not trigger re-renders, including it in a dependency array serves no functional purpose. ESLint may warn about this because it cannot always distinguish between refs and other values that should trigger re-execution.

Typical symptoms

  • ESLint warning "React Hook useEffect has a missing dependency: 'myRef'. Either include it or remove the dependency array"
  • Yellow squiggly lines in your IDE under the dependency array when a ref is used but not listed
  • Build warnings in CI/CD pipelines about exhaustive-deps violations involving refs
  • Confusion about whether to add refs to dependency arrays despite no functional issues
  • ESLint warning specifically mentions a variable created with useRef
  • Warning appears even though the code works correctly without the ref in the dependencies

Common causes

  1. Using a ref inside useEffect, useCallback, or useMemo without listing it in the dependency array, triggering ESLint's exhaustive-deps rule
  2. ESLint cannot distinguish between stable refs and other values, so it conservatively warns about all unlisted values
  3. Accessing ref.current inside a hook callback while the ref itself is not in the dependency array
  4. Passing a ref as a prop to a component and using it in a hook, causing ESLint to treat it like any other prop
  5. Using custom hooks that accept refs as parameters, confusing ESLint's dependency tracking
  6. Misunderstanding that the ref object itself is stable even though ref.current can change

How to fix "React Hook useRef has a missing dependency:"

1Understand that refs are intentionally stable and typically should not be dependencies

The ref object returned by useRef never changes between renders - only ref.current can be mutated. Since mutations to ref.current do not trigger re-renders, including the ref in a dependency array does nothing. React's design intentionally makes refs stable so they can be used to store mutable values that persist without causing re-renders.

typescript
function MyComponent() {
  const countRef = useRef(0);
  
  useEffect(() => {
    // Using countRef here - should it be a dependency?
    countRef.current += 1;
    console.log('Render count:', countRef.current);
  });
  
  // countRef object never changes, so no need to list it as a dependency
}
2Either include the ref in the dependency array or suppress the warning

You have two valid options: (1) Include the ref in the dependency array. This satisfies ESLint and is harmless since the ref is stable - it won't cause extra re-runs. (2) Add an ESLint disable comment if you're confident the ref doesn't need to be tracked.

typescript
// Option 1: Include the ref (harmless, satisfies ESLint)
function MyComponent() {
  const inputRef = useRef<HTMLInputElement>(null);
  
  useEffect(() => {
    inputRef.current?.focus();
  }, [inputRef]); // Including ref is safe and silences the warning
}

// Option 2: Suppress the warning (use sparingly)
function MyComponent() {
  const inputRef = useRef<HTMLInputElement>(null);
  
  useEffect(() => {
    inputRef.current?.focus();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []); // Explicitly stating empty deps is intentional
}
3If you need to react to ref.current changes, use useState instead

If you actually need your effect to re-run when a value changes, don't use useRef - use useState or useReducer instead. The fundamental purpose of refs is to store values that can change without triggering re-renders. If you need re-renders, you need state, not a ref.

typescript
// WRONG - trying to react to ref changes
function MyComponent() {
  const valueRef = useRef(0);
  
  useEffect(() => {
    console.log('Value changed:', valueRef.current);
  }, [valueRef.current]); // This won't work as expected!
  
  const increment = () => {
    valueRef.current += 1; // Mutation doesn't trigger re-render or effect
  };
}

// CORRECT - use state if you need to react to changes
function MyComponent() {
  const [value, setValue] = useState(0);
  
  useEffect(() => {
    console.log('Value changed:', value);
  }, [value]); // Effect properly runs on value changes
  
  const increment = () => {
    setValue(v => v + 1); // State update triggers re-render and effect
  };
}
4For DOM element refs, access them safely without dependencies

When using refs to access DOM elements, the ref object itself is stable. You can safely access ref.current in effects without listing the ref as a dependency, as long as you handle the case where ref.current might be null.

typescript
function MyComponent() {
  const divRef = useRef<HTMLDivElement>(null);
  
  useEffect(() => {
    // Access DOM element through ref
    if (divRef.current) {
      const width = divRef.current.offsetWidth;
      console.log('Div width:', width);
    }
    // No need to list divRef as a dependency
  }, []);
  
  return <div ref={divRef}>Content</div>;
}
5Configure ESLint to understand your custom hooks with refs

If you've created custom hooks that accept refs as parameters, you may need to configure ESLint to understand them. Use the additionalHooks option in your ESLint config to teach the exhaustive-deps rule about your custom hooks.

json
// .eslintrc.json
{
  "rules": {
    "react-hooks/exhaustive-deps": [
      "warn",
      {
        "additionalHooks": "(useMyCustomHook|useAnotherHook)"
      }
    ]
  }
}
6Review the specific use case to ensure the warning is truly a false positive

In rare cases, ESLint might be correctly warning you about a potential issue. Review your code: Are you conditionally creating the ref? Are you passing refs from props that might change? Are you using ref.current in a way that expects fresh values each render? If any of these apply, reconsider your approach.

typescript
// SUSPICIOUS - ref from props might actually change
function MyComponent({ externalRef }: { externalRef: RefObject<HTMLElement> }) {
  useEffect(() => {
    externalRef.current?.focus();
  }, []); // Should externalRef be a dependency? Probably yes!
}

// BETTER - include prop refs as dependencies
function MyComponent({ externalRef }: { externalRef: RefObject<HTMLElement> }) {
  useEffect(() => {
    externalRef.current?.focus();
  }, [externalRef]); // Safer to include refs from props
}

Advanced notes

The distinction between stable values (like refs) and reactive values (like state) is fundamental to React's mental model. Kent C. Dodds explains that you shouldn't put refs in dependency arrays because "it's an indication that you want the effect callback to re-run when a value is changed, but you're not notifying React when that change happens." If you find yourself wanting an effect to re-run when ref.current changes, you're misusing refs - switch to useState. The exhaustive-deps rule is valuable for preventing stale closure bugs, but it has limitations: it cannot perform deep type analysis to determine if a value is stable, so it conservatively warns about everything. For refs passed as props, including them in the dependency array is safer because the prop itself might change to point to a different ref object (though this is rare). Some teams configure their ESLint to auto-fix this by always including refs, accepting that it's technically unnecessary but consistent. The React team is aware of these false positives (see GitHub issues #14920 and #23392) but hasn't implemented special handling because (1) including refs is harmless and (2) distinguishing refs from other values requires complex static analysis.

Frequently asked questions

What does "React Hook useRef has a missing dependency:" mean?
This ESLint warning comes from the react-hooks/exhaustive-deps rule, which validates that all values used inside useEffect, useCallback, useMemo, and other hooks are properly listed in their dependency arrays. The rule helps prevent stale closure bugs by ensuring hooks re-run when their dependencies change. However, when it flags useRef, it's often a false positive or indicates a misunderstanding of how refs work.
How do I fix "React Hook useRef has a missing dependency:"?
ESLint's exhaustive-deps rule warns when a ref created with useRef is used inside useEffect but not listed in the dependency array. However, refs are intentionally stable and should typically not be included as dependencies since mutating ref.current does not trigger re-renders. Understanding when to include or exclude refs prevents confusion and maintains proper hook behavior.
What causes "React Hook useRef has a missing dependency:"?
Using a ref inside useEffect, useCallback, or useMemo without listing it in the dependency array, triggering ESLint's exhaustive-deps rule ESLint cannot distinguish between stable refs and other values, so it conservatively warns about all unlisted values Accessing ref.current inside a hook callback while the ref itself is not in the dependency array
Is the "React Hook useRef has a missing dependency:" error serious?
It is a low-severity error โ€” more of a blocker than a risk. The steps above resolve it.

Official resources & further reading