javascriptreactjsreact-hooks

Check if a function is created by useCallback?


I have hooks that accept functions as arguments. If the functions change unnecessarily, then it could cause extra re-renders. I want to ensure that the functions are wrapped with useCallback.

I.e. here's a simplified version:

function useApi({ onSuccess }) {
  if (process.env.NODE_ENV !== 'production' && !isUseCallback(onSuccess)) {
    throw new Error();
  }

  useEffect(() => {
    fetch(...)
      .then(res => res.json())
      .then(onSuccess);
  }, [onSuccess]);
}

If onSuccess changes unnecessarily, then it'll call the API unnecessarily. Is it possible to have the function isUseCallback? I think I'd have to write a custom useCallback that wraps React's useCallback.


Solution

  • I solved this using Typescript:

    type UseCallback<T extends (...args: any[]) => any> = T & { __IS_USE_CALLBACK: true };
    
    declare function useCallback<T extends (...args: any[]) => any>(
      callback: T,
      deps: ReadonlyArray<any>,
    ): UseCallback<T>;
    

    .

    function useApi(onSuccess: UseCallback<() => any>): any {}
    
    useApi(() => {}); // Error
    useApi(useCallback(() => {}, [])); // No error