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

gio*_*gim 21 javascript reactjs react-hooks usecallback

考虑这个例子:

 let memoizedCb = React.useCallback(
    memoize((param) => () => someFunction(param)),
    []
  );
Run Code Online (Sandbox Code Playgroud)

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

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

我发现这个线程,如果我们适应我的用例,会建议将此作为解决方案(如果我没有错的话):

const memoizedCb = React.useMemo(
  () => memoize((param) => () => someFunction(param)),
  []
);
Run Code Online (Sandbox Code Playgroud)

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

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

gio*_*gim 20

似乎警告是存在的,因为useCallback(也useMemo见下文)期望内联函数作为参数(但不知道为什么)。

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

const memoizedCb = React.useMemo(
  () => memoize((param) => () => someFunction(param)),
  []
);
Run Code Online (Sandbox Code Playgroud)

他们过去常常useMemo模仿功能 useCallback,同时还传递内联函数useMemo作为所需的警告:

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


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

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


sam*_*sam 9

作为更一般的解释,以下内容将产生警告:

const someFuncWrap = (fn) => (e) => fn(e)
const memoizedFunc = useCallback(someFuncWrap(foo), [someFuncWrap, foo]);
Run Code Online (Sandbox Code Playgroud)

通过内联函数将 更改useCallback为 a 。useMemo

const someFuncWrap = (fn) => (e) => fn(e)
const memoizedFunc = useMemo(() => someFuncWrap(foo), [someFuncWrap, foo]);
Run Code Online (Sandbox Code Playgroud)

这是因为要解析钩子 eslint 需要以以下形式查看它:

useMemo(() => foo, [foo]);
useCallback((bar) => foo(bar), [foo]);
Run Code Online (Sandbox Code Playgroud)


ALD*_*ENT 5

据我所知, useCallback 需要一个内联函数。如果您传递从另一个函数返回的函数,eslint 将无法弄清楚该函数的依赖项是什么,因此它将显示此警告。

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