Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/417.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 检查函数是否由useCallback创建?_Javascript_Reactjs_React Hooks - Fatal编程技术网

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