HiveBrain v1.2.0
Get Started
← Back to all entries
snippetreactCritical

How to fix missing dependency warning when using useEffect React Hook

Submitted by: @import:stackoverflow-api··
0
Viewed 0 times
whenfixhookwarningreactusingdependencyhowmissinguseeffect

Problem

With React 16.8.6 (it was good on previous version 16.8.3), I get this error when I attempt to prevent an infinite loop on a fetch request:

./src/components/BusinessesList.js
Line 51:  React Hook useEffect has a missing dependency: 'fetchBusinesses'.
Either include it or remove the dependency array  react-hooks/exhaustive-deps


I've been unable to find a solution that stops the infinite loop. I want to stay away from using useReducer(). I did find this discussion [ESLint] Feedback for 'exhaustive-deps' lint rule #14920 where a possible solution is You can always // eslint-disable-next-line react-hooks/exhaustive-deps if you think you know what you're doing. I'm not confident in what I'm doing, so I haven't tried implementing it just yet.

I have this current setup, React hook useEffect runs continuously forever/infinite loop and the only comment is about useCallback() which I'm not familiar with.

How I'm currently using useEffect() (which I only want to run once in the beginning similar to componentDidMount()):

useEffect(() => {
    fetchBusinesses();
  }, []);


const fetchBusinesses = () => {
    return fetch("theURL", {method: "GET"}
    )
      .then(res => normalizeResponseErrors(res))
      .then(res => {
        return res.json();
      })
      .then(rcvdBusinesses => {
        // some stuff
      })
      .catch(err => {
        // some error handling
      });
  };

Solution

If you aren't using fetchBusinesses method anywhere apart from the effect, you could simply move it into the effect and avoid the warning

useEffect(() => {
    const fetchBusinesses = () => {
       return fetch("theURL", {method: "GET"}
    )
      .then(res => normalizeResponseErrors(res))
      .then(res => {
        return res.json();
      })
      .then(rcvdBusinesses => {
        // some stuff
      })
      .catch(err => {
        // some error handling
      });
  };
  fetchBusinesses();
}, []);


If however you are using fetchBusinesses outside of the effect, you must note two things

  • Is there any issue with you not passing fetchBusinesses as a method when it's used during mount with its enclosing closure?



  • Does your method depend on some variables which it receives from its enclosing closure? This is not the case for you.



  • On every render, fetchBusinesses will be re-created and hence passing it to useEffect will cause issues. So first you must memoize fetchBusinesses if you were to pass it to the dependency array.



To sum it up I would say that if you are using fetchBusinesses outside of useEffect you can disable the rule using // eslint-disable-next-line react-hooks/exhaustive-deps otherwise you can move the method inside of useEffect

To disable the rule you would write it like

useEffect(() => {
   // other code
   ...
 
   // eslint-disable-next-line react-hooks/exhaustive-deps
}, [])

Code Snippets

useEffect(() => {
    const fetchBusinesses = () => {
       return fetch("theURL", {method: "GET"}
    )
      .then(res => normalizeResponseErrors(res))
      .then(res => {
        return res.json();
      })
      .then(rcvdBusinesses => {
        // some stuff
      })
      .catch(err => {
        // some error handling
      });
  };
  fetchBusinesses();
}, []);
useEffect(() => {
   // other code
   ...
 
   // eslint-disable-next-line react-hooks/exhaustive-deps
}, [])

Context

Stack Overflow Q#55840294, score: 776

Revisions (0)

No revisions yet.