【发布时间】:2020-06-09 12:23:43
【问题描述】:
我无法完全理解 linter 规则 react-hooks/exhaustive-deps 中的依赖关系。在我看来,在许多情况下,您不需要数组中的特定变量,因为您不希望在该变量更改时调用挂钩。但是,这个 linting 规则会告诉你,如果它在钩子内部,它就会从依赖项中丢失。我知道我可以禁用该行,但我想知道我是否对规则有误解,以及是否有更好的方法来使用钩子对这个功能进行编码。这是我觉得不需要应用此规则的代码示例。
我有以下两个状态变量:
const [taggedUsers, setTaggedUsers] = useState([])
const [users, setUsers] = useState([])
taggedUsers 表示与实体相关联的用户(其中仅保存用户的电子邮件字符串),而用户是从另一个 api 获取的用户对象,它具有比用户的电子邮件更多的信息。
我有一个带有钩子的组件,该钩子在被调用时会结合 taggedUser 对象,以便我可以在页面上显示它们的名称。当我加载页面时,我点击的给我实体的端点有一个属性 taggedUsers ,它只是与实体关联的电子邮件列表。我有一个转换器,它接收这些电子邮件并将它们映射到一个看起来像这样的 taggedUser 对象列表:
{ email: "john.smith@gmail.com", name: null, id: "john.smith@gmail.com" }
水化后,物体将如下所示:
{ email: "john.smith@gmail.com", name: "John Smith", id: "john.smith@gmail.com" }
我有一个端点,我可以点击它来获取用户列表,并使用从那里获取的数据来补充用户对象的名称。当我的组件首次呈现时,我获取用户,并将变量“users”的状态设置为这些用户。用户的变化然后触发下一个钩子:
useEffect(() => {
const hydrateTaggedUsers = () => {
const hydratedTaggedUsers = []
users.forEach((user) => {
taggedUsers.forEach((taggedUser) => {
if (user.email === taggedUser.email) hydratedTaggedUsers.push(user)
})
})
setTaggedUsers(hydratedTaggedUsers)
}
if (users.length) hydrateTaggedUsers()
}, [users])
我只希望在“用户”更改时调用此挂钩一次,每次页面加载仅调用一次。根据 linter 设置,挂钩的依赖项中缺少 taggedUsers。但是,我不希望在 taggedUsers 的值发生更改时调用此挂钩,并将其添加为依赖项会导致堆栈溢出,因为此挂钩会更改 taggedUsers 的值。
关于如何构建钩子,我有什么遗漏吗?对我来说,因为我不希望在更新 taggedUsers 的值时调用这个钩子,所以它不应该包含在依赖数组中。但是,linter 仍然希望它在那里。在这种情况下,禁用线路是不可避免的吗?
【问题讨论】:
标签: javascript reactjs react-hooks eslint