Passing thoughts - dependancy array (compiler warning)

I’ve been working on this project off platform. I created a new react app, copied relevant files, and it all worked fine until I received the following warning message from the complier:

Compiled with warnings.

src/Thought.js
  Line 18:6:  React Hook useEffect has a missing dependency: 'removeThought'. 
  Either include it or remove the dependency array  react-hooks/exhaustive-deps

The page renders fine with ‘thoughts’ being removed both manually and automatically as intended. My useEffect() hook looks like this.

useEffect(() => {
    const remainingTime = thought.expiresAt - Date.now();
    const timeoutID = setTimeout(() => {
        removeThought(thought.id);
    }, remainingTime);
    return () => {
        clearTimeout(timeoutID);
    };
  }, [thought]);

To see what happens I added ‘removeThought()’ reference to the dependancy array, and it got rid of the warning while the app is still working correctly.

useEffect(() => {
    const remainingTime = thought.expiresAt - Date.now();
    const timeoutID = setTimeout(() => {
        removeThought(thought.id);
    }, remainingTime);
    return () => {
        clearTimeout(timeoutID);
    };
  }, [thought, removeThought]);

Complier happy and app fully operational.

Compiled successfully!

You can now view passing-thoughts in the browser.

So, my question is this:

Why is react complier asking me to add ‘removeThougth’ to dependancy array? (Project instructions do not mention it).

It kind of doesn’t make sense to me… :thinking:

A project started with Create React App will have extra ESLint plugins and rules enabled by default, including the eslint-plugin-react-hooks plugin and the rule “react-hooks/exhaustive-deps”, which you’ve experienced here. You can read more about it and why it’s included by default here

The way the effects are being used in this project won’t have a chance for it to cause a problem, but it’s still a best practice to include it in the dependency array anyway. Is it safe to omit functions from the list of dependencies? It’s also possible to turn off that warning, but I wouldn’t recommend it.

Here’s a post from StackOverflow that I found when I first saw a warning about it too that gives an example of a function possibly changing between renders.

1 Like

Perfect! Thanks for amazing answer! :+1:

1 Like

So…
I decided to add reference requested by esLint.

Also, the more I read about this, the more it seems to me that this should really be addressed in Codecademy lessons about Hooks.

Possible routes one could take…

1. Ignore the warning - that’s where the project’s official instructions lead you, but according to React docs it’s incorrect.

It is only safe to omit a function from the dependency list if nothing in it (or the functions called by it) references props, state, or values derived from them. This example has a bug:

function ProductPage({ productId }) {
  const [product, setProduct] = useState(null);

  async function fetchProduct() {
    const response = await fetch('http://myapi/product/' + productId); // Uses productId prop    const json = await response.json();
    setProduct(json);
  }

  useEffect(() => {
    fetchProduct();
  }, []); // 🔴 Invalid because `fetchProduct` uses `productId`  // ...
}

2. Add the requested reference to your dependency array - follow React docs which seems to contradict these lessons, which specifically state that dependancy array is meant to be either empty or to contain elements that (on change) should cause the hook to run again.

3. Adding // eslint-disable-next-line before the offending line, which would instruct esLint to ignore the following line. This is strongly discouraged by Dan Abramov from Facebook (here), according to whom these warnings indicate potential vulnerabilities in code, which should be refactored.

1 Like