| Like others I disagree that you have to wrap _everything_ in useCallback/useMemo. However saying you only need those for performance reasons is wrong. There are cases where avoiding re-rendering (thanks to useCallback) is avoiding an infinite loop. I created a codesandbox[1] to illustrate this. Wrapping the "reset" function in a useCallback solves the infinite loop. If your initial reaction is: "you should not create logic like this" or "you're adding unnecessary stuff" please note that this is a stripped down version of a real use case, where things make more sense. The point is that it's hard to come up with a rule as to when to use useCallback. The best I can think about is: "if you don't have direct vision on where your function will be consumed, wrap it in useCallback". For example, when your function is defined and returned in a hook or defined in a parent component and given to children. The point is that any of those children/consumers could have this function in a useEffect and so list it as a dependency of this useEffect. [1]: Warning, clicking "Start" creates an infinite loop in your browser. https://codesandbox.io/s/intelligent-rgb-6nfrt3 |
There's no reason to reset before setting data again, and I'm not sure why you'd even consider putting the functions in the dependency array for the useEffect in usePets.
I can imagine reasons you'd want to setData in a useEffect (maybe when something else changes, or the user performs some interaction, you fetch new data and then set it), but the dependency would be the thing that indicates that action has happened, and not a reset function returned by a custom hook coupled with your data and setter function.