Short answer
Don’t silence the rule. If the missing item is a function, move the function inside the effect, so only the values it reads become dependencies. If it is an object or function you can’t move, wrap it in useCallback or useMemo. If the effect only updates state from its previous value, use the updater form setCount(c => c + 1) and drop count from the list. Then add whatever the linter still asks for.
What is missing, and how to add it without a loop
01
A function from the component body
“Every reactive value used by your Effect’s code must be declared in your dependency list.” React, Removing Effect Dependencies
A function declared in the component is a new function on every render, so adding it makes the effect run every time. Move it inside the effect; then the linter asks only for the values it uses, such as userId.
// warns: fetchUser is missing const fetchUser = () => api.get(`/users/${userId}`).then(setUser); useEffect(() => { fetchUser(); }, []); // works: the function lives in the effect useEffect(() => { api.get(`/users/${userId}`).then(setUser); }, [userId]);02
A function or object you can’t move
“Validates that dependency arrays for React hooks contain all necessary dependencies.” React, exhaustive-deps
If the function is also used outside the effect, or comes from a custom Hook, wrap it in useCallback (or an object in useMemo) with its own dependencies, so it only changes when they do.
const fetchUser = useCallback( () => api.get(`/users/${userId}`).then(setUser), [userId] ); useEffect(() => { fetchUser(); }, [fetchUser]);03
State that the effect also sets
An effect that reads count to set count loops once count is a dependency. Use the updater form, which receives the latest value, and remove count from the list.
useEffect(() => { const id = setInterval(() => setCount((c) => c + 1), 1000); return () => clearInterval(id); }, []);04
A function or object passed in as a prop
An onChange or options prop created inline in the parent is new on every render, so listing it reruns the effect every time, often in a loop. Wrap it in useCallback or useMemo in the parent, or move the object literal out of the render. setState functions and refs are stable and never need listing. For logic that should read the latest props without rerunning the effect, React 19.2 adds useEffectEvent.
05
An eslint-disable comment that hides a bug
“Suppressing the linter leads to very unintuitive bugs that are hard to find and fix.” React, Removing Effect Dependencies
Disabling the rule for the line keeps the warning quiet but leaves the effect reading old values. Remove the comment and use one of the fixes above.
Checked against the vendor’s docs on : React: Removing Effect Dependencies; React: exhaustive-deps lint rule; React reference: useEffect.
Rather hand it over?
Fixed scope, fixed price, paid upfront. The work happens in writing; no call needed.
- from $450App Fix TicketOne reproducible bug in an existing mobile or web app, diagnosed and fixed.See scope and start
- from $450AI-Built App RescueA Lovable, Bolt or Cursor app checked end to end in 3 days, then its worst problems fixed at a fixed price.No issues worth fixing, no charge. If the Launch Check finds nothing rated medium or higher, Simon refunds the full $450. You keep the report either way. This applies to the first 10 Launch Checks bought after October 30, 2026.See scope and start
Related: React “Maximum update depth exceeded” · React “Too many re-renders” · React useEffect with an async function