【问题标题】:What can be a dependency for React hooks?React 钩子的依赖项是什么?
【发布时间】:2020-07-14 18:49:46
【问题描述】:

查看文档,this section [已编辑链接] 底部有一条注释,看起来好像只有 props 或 state 应该在挂钩依赖项列表中使用。但是,当在列表中使用 props 或 state 上的“复杂表达式”时,eslint 插件会给出以下内容:

React Hook useEffect 在依赖数组中有一个复杂的表达式。将其提取到一个单独的变量中,以便对其进行静态检查。 eslint(react-hooks/exhaustive-deps)

这让我思考什么可以用作依赖项。我们可以使用从 props 计算的局部变量吗?在这种情况下,我们是否需要创建某种新的状态变量或 ref?我不确定钩子是在组件内就地执行(因此局部变量可用)还是从渲染的上下文中提升(所以我们必须只使用状态、道具或其他钩子值,如 refs/memos )。

示例

一个组件有一个道具,数据,它是一个对象。

data: {
  name: 'name',
  id: 2
}

1) 看起来data.name 可以在依赖项中使用。但是我们可以使用设置为属性的局部变量吗?

const { name } = data;

useEffect(fn, [name]);

2) 我们能否使用由依赖数组中的 prop 计算的变量?

const isOdd = Boolean(data.id % 2);

useEffect(fn, [isOdd]);

这两种情况似乎都适用于小型测试。我对 Hooks 不够了解,无法知道它是否违反了一些规则,从而导致结果不确定。

【问题讨论】:

  • "...看起来好像只有 props 或 state 应该用在钩子依赖列表中" 你是怎么得出这个结论的?除了useState 可以访问自己的本地状态之外,真的没有提到状态或道具。
  • 我打开了太多标签并复制了错误的链接。更新了正确的链接。 reactjs.org/docs/…

标签: reactjs react-hooks


【解决方案1】:

Optimizing Performance by Skipping Effects 可能有助于理解钩子依赖。

注意

如果您使用此优化,请确保数组包含所有值 从改变的组件范围(例如道具和状态) 时间和效果所使用的时间。 否则,您的代码将 从以前的渲染中引用过时的值。了解更多关于如何 处理函数以及当数组变化太频繁时该怎么办。

重要的一点,“...来自组件范围的所有值...”,表示在钩子中使用的组件范围内的任何值。

问:我们可以使用根据 props 计算的局部变量吗?

  • 是的

问:在这种情况下我们是否需要创建某种新的状态变量或引用?

  • 没有

问:我不确定钩子是在组件内就地执行(因此局部变量可用)还是从渲染上下文中提升(所以我们必须只使用state、props 或其他挂钩值,如 refs/memos)

  • AFAIK,它们只是反应中具有特殊规则的函数。它们在功能组件的范围内被调用。

【讨论】:

  • 我感到困惑的部分是在那张纸条的后面。 “如果你想运行一个效果并且只清理一次(在挂载和卸载时),你可以传递一个空数组 ([]) 作为第二个参数。这告诉 React 你的效果不依赖于任何来自道具或状态,所以它永远不需要重新运行。”这里的第二句话说空数组意味着它不依赖于状态或道具。但实际上,这意味着它不依赖于组件范围内的任何值。对吗?
  • 该注释的其余部分讨论了使用挂钩来模拟您从基于类的生命周期函数 componentDidMountcomponentWillUnmount 获得的行为,并使用挂钩 lint 规则来帮助不犯逻辑错误在钩子里。有没有让您感到困惑的特定部分?
  • 您可以将钩子视为在组件内完全执行 - 这就是为什么钩子必须以相同的顺序运行并且不能有条件地调用的原因。 100% 必须包含您在挂钩函数中使用的任何变量,这些变量可能会在渲染之间发生变化。如果你不这样做,东西最终会以一种非常混乱的方式中断。钩子是被记忆的,所以如果依赖数组中的值自上次调用钩子以来没有改变,那么钩子将不会被再次调用。
  • 牢记“组件范围内的所有值” 部分,其余部分似乎是有道理的。感谢您的帮助。
猜你喜欢
  • 1970-01-01
  • 2021-01-21
  • 2015-04-13
  • 2018-02-08
  • 2021-01-28
  • 2013-01-20
  • 1970-01-01
  • 2017-10-25
  • 1970-01-01
相关资源
最近更新 更多