Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to fix missing dependency warning when using useEffect React Hook

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       });   }; 
like image 546
russ Avatar asked Apr 25 '19 00:04

russ


People also ask

How do you fix React hooks exhaustive DEPS?

The "react-hooks/exhaustive-deps" rule warns us when we have a missing dependency in an effect hook. To get rid of the warning, move the function or variable declaration inside of the useEffect hook, memoize arrays and objects that change on every render or disable the rule.

How do you fix the infinite loop inside useEffect React hooks?

To get rid of your infinite loop, simply use an empty dependency array like so: const [count, setCount] = useState(0); //only update the value of 'count' when component is first mounted useEffect(() => { setCount((count) => count + 1); }, []); This will tell React to run useEffect on the first render.

What is a missing dependency?

Missing dependencies are those dependencies that are not available in the repository, so you cannot add them to your deployment set. You can set Deployer to ignore missing dependencies when you create the project (see Creating a Project) or when you check unresolved dependencies.

What happens if you don't pass dependency in useEffect?

Empty dependency array So what happens when the dependency array is empty? It simply means that the hook will only trigger once when the component is first rendered. So for example, for useEffect it means the callback will run once at the beginning of the lifecycle of the component and never again.


1 Answers

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 render, you must note two things

  1. Is there any issue with you not passing fetchBusinesses as a method when it's used during mount with its enclosing closure?
  2. Does your method depend on some variables which it receives from its enclosing closure? This is not the case for you.
  3. 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 }, [])  
like image 129
Shubham Khatri Avatar answered Oct 25 '22 04:10

Shubham Khatri