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
.
Answer
I solved this using Typescript:
type UseCallback<T extends (...args: any[]) => any> = ((...args: Parameters<T>) => ReturnType<T>) & { __IS_USE_CALLBACK?: undefined }; 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