React Hook useCallback 接收到一个依赖项未知的函数。改为传递内联函数

React Hook useCallback received a function whose dependencies are unknown. Pass an inline function instead

考虑这个例子:

 let memoizedCb = React.useCallback(
    memoize((param) => () => someFunction(param)),
    []
  );

其中 memoize 来自外部库,如“fast-memoize”。上面的代码给出了警告:

React Hook useCallback received a function whose dependencies are unknown. Pass an inline function instead

我找到了 this 个线程,如果我们适应我的用例,会建议将此作为解决方案(如果我没记错):

const memoizedCb = React.useMemo(
  () => memoize((param) => () => someFunction(param)),
  []
);

警告是关于什么的? 为什么 useMemo 解决了这个问题?

注意:someFunction 是在函数组件外部定义的,因此不需要作为依赖项。

来自React docs

useCallback will return a memoized version of the callback that only changes if one of the dependencies has changed. This is useful when passing callbacks to optimized child components that rely on reference equality to prevent unnecessary renders

您看到警告是因为您在使用 useCallback 挂钩时没有传递任何依赖项。

此外,

useCallback(fn, deps) is equivalent to useMemo(() => fn, deps).

据我所知,useCallback 需要一个内联函数。如果你从另一个函数传递一个返回的函数,eslint 将无法找出函数的依赖项,所以它会显示这个警告。

我认为,eslint 无法确定 somefunction 的依赖关系,因此它无法评估 react-hooks/exhaustive-deps 规则,因为要评估此规则,eslint 应该能够识别是否存在任何依赖关系,例如状态,传递给 useCallback 钩子的函数的道具。所以 eslint 要求您传递一个内联函数,它会理解并可以评估 lint 规则。

似乎存在警告是因为 useCallback(以及 useMemo 见下文)期望内联函数作为参数(虽然不知道为什么)。

所以在问题的解决方案中:

const memoizedCb = React.useMemo(
  () => memoize((param) => () => someFunction(param)),
  []
);

他们使用 useMemo 模仿 useCallback 功能,同时还将 内联 函数传递给 useMemo 作为警告要求:

React Hook useCallback received a function whose dependencies are unknown. Pass an inline function instead


该警告并非特定于 useCallback,如果您在第一个示例中将 useCallback 替换为 useMemo,您会收到相同的警告:

 // For testing
 // Gives same warning
 let memoizedCb = React.useMemo(
    memoize((param) => () => someFunction(param)),
    []
 );