Search code examples
javascriptreactjsparameter-passingreact-hooksmemoization

Is there a way to memoize a function passed from params - (useCallback) exhaustive-deps


So I have this little snippet:

const useTest = (callbackFunc) => {
    const user = useSelector(selector.getUser); //  a value from store

    useEffect(() => {
      if (user.id === 1) {
         callbackFunc()
      }
    }, [callbackFunc, user.id])

}

On the code above if callbackFunc is not memoized (wrapped in useCallback) before passing, the useEffect will trigger an infinite loop.

Wrapping the function on a useCallback inside the hook will still trigger an infinite loop, so that's a no:

const cb = () => useCallback(() => callbackFunc, [callbackFunc]);

The above will trigger infite loop because callbackFunc.

YES I am well aware that I can just wrap the function inside useCallback before passing to this hook, my only problem with that is: there will be a high probability that other/future devs will just pass a non-memoized function when calling this hook and this is what worries me. `

I can't remove the callbackFunc on the useEffect/useCallback second parameter array because of exhaustive-deps rule - and removing it (or on this line) is also prohibited by the higher devs.

Any idea how can I possibly achieve my goal? If none thatn I'll just pray that other devs will read the hook first before using it.


Solution

  • You can do something like this, but you won't be able to modify the callback anymore

    const funcRef = React.useRef(null)
    useEffect(() => {
     funcRef = callbackFunc
    }, [])
    
    useEffect(() => {
       if (funcRef.current){
        if (user.id === 1) {
          funcRef.current()
        }
       }
    }, [funcRef, user.id])