Avoiding Unnecessary Firing

An effect that re-runs whenever an unrelated value changes is usually reading something it does not need. A timer is the clearest case: setCount(count + 1) needs count, so count must be a dependency, so React 7,897 clears and recreates the interval on every tick. The updater form needs no dependency at all.

One interval for the lifetime of the componentJavaScript
function Counter() {
  const [count, setCount] = useState(0);
  useEffect(() => {
    console.log('subscribing');                 // logged once, not once per second
    const id = setInterval(() => setCount(c => c + 1), 1000);
    return () => clearInterval(id);
  }, []);                                       // reads no reactive value
  return <h1>{count}</h1>;
}
Output
subscribing

Three moves remove most spurious dependencies:

Deleting a dependency the linter asked for never works: the effect then fires with values from an old render, and the bug moves from "too often" to "silently wrong". Separating Events from Effects has the supported way to say that a value is not reactive.