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
.
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