【问题标题】:React Hook useCallback received a function whose dependencies are unknown. Pass an inline function insteadReact Hook useCallback 收到一个依赖未知的函数。改为传递内联函数
【发布时间】:2021-11-03 19:04:22
【问题描述】:

考虑这个例子:

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

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

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

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

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

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

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

【问题讨论】:

  • 这是一个 linter 警告,而不是实际错误。您可以忽略它,也可以使用不会触发它的模式(例如您从该 github 线程获得的useMemo)。
  • @JaredSmith 我看到这是一个 linter 警告我试图解释为什么 useMemo 没有警告
  • 询问编写 eslint 插件的人。你说得对,两者在逻辑上是等价的。也许有相同的规则,毕竟你将一个内联函数传递给useMemo
  • @JaredSmith 是的,这就是我感到困惑的原因,因为两者看起来一样:)
  • useCallback 已经记住了函数,因此使用另一个实用程序来记住内联函数是多余且不必要的。

标签: javascript reactjs react-hooks usecallback


【解决方案1】:

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

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

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

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

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


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

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

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

    • 它不是在抱怨someFunction,而是在抱怨memoize。我更感兴趣的是为什么在第二种情况下没有警告
    【解决方案3】:

    来自React docs

    useCallback 将返回回调的记忆版本,仅 如果依赖项之一发生更改,则更改。这在将回调传递给依赖引用相等以防止不必要的渲染的优化子组件时很有用

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

    还有,

    useCallback(fn, deps) 等价于useMemo(() => fn, deps)

    【讨论】:

    • 不,不是这样,在这些情况下,您会收到不同的警告。注意“received a function其依赖关系未知”。它抱怨它收到了 memoize 功能。在那些情况下,你说它会给你一个关于缺少依赖项的警告。
    猜你喜欢
    • 2020-04-26
    • 2019-08-05
    • 1970-01-01
    • 2020-10-17
    • 2021-06-17
    • 2022-01-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多