Alex Vipond
SHIFT + D

Don't disable ESLint exhaustive dependencies—conquer it

https://www.epicreact.dev/myths-about-useeffecthttps://github.com/facebook/react/issues/14920

useEffect is weird. It can and will crush you if you're not careful with how you write effects, and especially how you list your effects' dependencies.

The react/exhaustive-deps ESLint rule is a frustratingly indispensable tool for this task. It tells you when you're about to f🐥ck up, but it's not smart enough to detect when dependencies have intentionally been omitted to make sure an effect doesn't run too often.

Then again, the React authors didn't really intend for people to intentionally omit certain data from an effect. The React docs offer this ultimatum:

You don’t choose what to put on the useEffect dependency list. The list describes your code. To change the dependency list, change the code.

An absolute banger! Really lays down the law, and strict laws are what we need when dealing with React's trickiest feature.

But in practice, I thik

import { useRef } from 'react';

/**
 * Just like `useMemo`, but the returned value is a
 * non-reactive ref.
 * 
 * This is useful for storing up-to-date values that you
 * can access inside a `useEffect`, but that you don't
 * want to include in the `useEffect`'s dependency array.
 */
export default function useSyncedRef<Type>(
  factory: (previous: Type) => Type
) {
  const ref = useRef<Type>();

  ref.current = factory(ref.current);

  return ref;
}

The React docs on removing effect dependencies are a great and thorough resource,

ON THIS PAGE

Don't disable ESLint exhaustive dependencies—conquer it