Why useEffect warns for the fields that I do not need to put in the dependencies array?

Viewed 219

I have gone through the useEffect documentation and I do not understand why I get warning for every variable and function that I use inside useEffect, but I have no dependency on them.

Consider my useEffect here

const [updatedComm, setUpdatedComm] = useState<ICommunication>(props.comm)
const [isEditOn, setIsEditOn] = useState<boolean | false>(false)
const getPublishedComm = () => { /* function implementation */ }
const dispatch = useDispatch();

useEffect(() => {
        if (!isEditOn && updatedComm !== props.comm) {
            const publishedComm = getPublishedComm()
            dispatch(editCommunication(publishedComm))
            setCurrentComm(publishedComm)
        }
    }, [isEditOn])

My only need to run this effect is when isEditOn changes. However, this code logs warnings

  Line 66:8:  React Hook useEffect has missing dependencies: 'dispatch', 'getPublishedComm', 'props.comm', and 'updatedComm'. Either include them or remove the dependency array  react-hooks/exhaustive-deps

What can I do to remove these warnings, or am I really missing something fundamentally?

Please help me understand.

Thank you

2 Answers

Do this to "silence" that warning,
especially if you're certain re-rendering should/shall be/is based on specific dependencies

useEffect(() => {
   if (!isEditOn && updatedComm !== props.comm) {
      const publishedComm = getPublishedComm();
      dispatch(editCommunication(publishedComm));
      setCurrentComm(publishedComm);
   }
   // eslint-disable-next-line
}, [isEditOn])

But from what I see, even updatedComm should part of that array of dependencies.
It's worth understanding the essence of the array of dependencies as regards performance optimization by skipping effects.

Because useEffect sees your usage of states, and state-setters, it's concerned that you have many changing things inside callback, but you using little dependencies.

Because in Functional component, function handler is also changed in new render

What you could do is - extract body of effect to avoid warning

But it's strongly unrecommended - if you feel like you doing something wrong, that's probably true, read docs again

function editChanged (isEditOn) { // only isEditOn guaranteed to be fresh
   if (!isEditOn && updatedComm !== props.comm) {
      const publishedComm = getPublishedComm();
      dispatch(editCommunication(publishedComm));
      setCurrentComm(publishedComm);
   }
}

useEffect(() => {
   editChanged(isEditOn)
}, [isEditOn])
Related