'React Hook useEffect has a missing dependency' warning with function

So I have this React component which uses the useEffect() hook:

const [stateItem, setStateItem] = useState(0);

useEffect(() => {
  if (condition) {
    myFunction();
  }
}, [stateItem]);

const myFunction = () => {
  return 'hello';
}

React gives me a warning about 'myFunction' being a missing dependency. I (think I) understand why and I've read through many similar questions asking for more or less the same thing, but the answer is always 'move your function into the useEffect hook'. This would be fine if not for myFunction being called from different places, e.g.:

...
return (
  <Button onClick={() => myFunction()} />
);

therefore I cannot put my function inside the useEffect hook.

One answer to a similar question was to put the function outside the component, but that would require me to pass a lot of data to my functions, e.g. const myFunction(stateItem, setStateItem, someProp) => { stuff };

which gets extremely tedious when there are several functions with many props, state hooks etc. to pass.

Aside from putting a linter ignore comment above the useEffect hook, is there anything more practical to do about this? I'm finding these things to make using react hooks very impractical.


So it seems like your aim is to keep your function inside your component and

  1. You don't want to move it inside useEffect since you want to use it elsewhere
  2. You don't want to move it outside your function since you want to avoid passing parameters from the component

In that case you i think the best solution is to use the useCallback hook as shown below

function YourComponent(props){

  const [stateItem, setStateItem] = useState(0);

  //wrap your logic in useCallback hook
  const myFunction = React.useCallback(
    () => {

      //if you use any dependencies in this function add them to the deps array of useCallback
      //so if any of the dependencies change thats only when the function changes

      return 'hello'
    }, [deps])

    useEffect(() => { 
       if(condition) {
          myFunction();
       }

    //add your function to the dependency array as well
    //the useCallback hook will ensure your function is always constant on every rerender thus you wont have any issues by putting it in the deps array, besides the #1 rule is NEVER LIE ABOUT YOUR DEPENDENCIES
    //the function only changes if the dependencies to useCallback hook change!!
    }, [stateItem, myFunction ])

   return (
     <Button onClick={() => myFunction()} />
   );
}


The useCallback hook will ensure your function is always constant on every rerender thus you wont have any issues by putting it in the deps array. the function only changes if the dependencies to useCallback hook change. By doing this we keep the golden rule of hooks which is NEVER LIE ABOUT YOUR DEPENDENCIES. Hope that helps. You might want to read this Blog Post By Dan Abramov


TLDR: Add myFunction to dependency array like below

React useEffect has thing called dependency array what this does basically helps you and react to know when to re run the effect. Basically you should put everything that is defined outside the effect.

In this effect you are putting stateItem as a dependency of this effect this means that every time it changes react will re run this effect. Now as you might have guess you are using myFunction which is as well defined outside the effect, which means that react should know when that updates so it is aware. To fix this warning just put the function has a item in the the dependency array like this.

const [stateItem, setStateItem] = useState(0);

useEffect(() => {
  if (condition) {
    myFunction();
  }
}, [stateItem, myFunction]);

const myFunction = () => {
  return 'hello';
}



I would suggest you not to use the useEffect at all, as far as I understood, you want to call a certain function whenever a certain state was updated. For this, I would suggest you rather to write a custom function which will be called on the spot where it would be updated (for example an Input).

Now you could just call this function and update your state, since you know this function will only be called when only this particular state is about to be updated and then you can call your other function afterwards.

If you have something like a changeHandler you could also do it in there but I would rather suggest to write a custom function.

Small example code:

const [stateItem, setStateItem] = useState(0);

const myFunction = () => {
   // do something
};

const myOtherFunc = (value) => {
   setStateItem(value);

   if (condition) {
      myFunction();
   }
};

I hope I understood your problem correctly and this was helpful.