Javascript 检查函数是否由useCallback创建?
我有接受函数作为参数的钩子。如果函数发生不必要的更改,则可能会导致额外的重新渲染。我想确保函数是用Javascript 检查函数是否由useCallback创建?,javascript,reactjs,react-hooks,Javascript,Reactjs,React Hooks,我有接受函数作为参数的钩子。如果函数发生不必要的更改,则可能会导致额外的重新渲染。我想确保函数是用useCallback包装的 也就是说,这里有一个简化版本: function useApi({ onSuccess }) { if (process.env.NODE_ENV !== 'production' && !isUseCallback(onSuccess)) { throw new Error(); } useEffect(() => {
useCallback
包装的
也就是说,这里有一个简化版本:
function useApi({ onSuccess }) {
if (process.env.NODE_ENV !== 'production' && !isUseCallback(onSuccess)) {
throw new Error();
}
useEffect(() => {
fetch(...)
.then(res => res.json())
.then(onSuccess);
}, [onSuccess]);
}
如果
onSuccess
不必要地更改,那么它将不必要地调用API。是否可以使用函数isUseCallback
?我想我必须编写一个自定义的useCallback
来包装React的useCallback
您可以将回调包装在useRef()
中,以确保useffect()
回调引用最近的onSuccess
:
函数useApi({onSuccess}){
const ref=useRef();
参考电流=成功;
useffect(()=>{
获取(…)
.then(res=>res.json())
.然后(val=>ref.current(val));
}, []);
}
编写
。然后(val=>ref.current(val))
而不仅仅是。然后(ref.current)
非常重要,这样在fetch()
解析之前,属性访问ref.current
不会发生。这样一来,ref.current
就等于传递给useApi()
的最近的onSuccess
,我使用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>;
键入UseCallback any>=
((…args:Parameters)=>ReturnType)和{uuu是使用回调吗?:undefined};
声明函数useCallback any>(
回叫:T,,
副总裁:ReadonlyArray,
):UseCallback;
函数useApi(onSuccess:UseCallback any>):any;
useApi(()=>{});//错误
useApi(useCallback(()=>{}));//无误
No,useCallback不以任何特殊方式标记生成的函数。而且你实现守卫的方式看起来有点古怪。所以有必要的改变,也有不必要的成功改变。你能先定义限定符吗?什么样的质量被认为是必要的/不必要的?我认为答案是确保onSuccess被包装在useCallback中,并确保其依赖关系不会改变。任何对象或函数都将无法通过相等(==)检查,除非它们分别包装在useMemo或useCallback中。您可以进行调整,但必须将if()
移动到挂钩内(不能有条件地调用)。
function useApi(onSuccess: UseCallback<() => any>): any;
useApi(() => {}); // Error
useApi(useCallback(() => {})); // No error