3

我使用 TypeScript 4 和 React 17

我在自定义钩子中有这段代码:

  const myValue = useMemo((): string[] => {
    if (someCondition) {
      return (myMap?.field && myMap.field.[subfieldId]) || null
    } else {
      ...
    }
  }, [myMap.field.[subfieldId]])

ESlint 抱怨必须将 myMap.field.[subfieldId] 移动到变量中以进行程序检查。

所以我改成这样:

  const currentData: string[] | null = (myMap?.field && myMap.field.[subfieldId]) || null

  const myValue = useMemo((): string[] => {
    if (someCondition) {
      return currentData
    } else {
      ...
    }
  }, [currentData])

我不确定让变量在上限范围内,在每次渲染时重新计算是一个好习惯,我什至担心会创建无限循环。

ESLint 建议我这样做,这要简单得多:

  const myValue = useMemo((): string[] => {
    if (someCondition) {
      return (myMap?.field && myMap.field.[subfieldId]) || null
    } else {
      ...
    }
  }, [myMap.field])

myMap.field 是否足以让 React 发现 myMap.field[subfieldId] 发生了变化?我想应该会的。确实,如果我只放 myMap,React 不会知道发生了什么变化,因为对象引用本身并没有改变,但是在比较之前和新的 myMap.field 时,React 会检查所有子字段。可以?

4

1 回答 1

1

根据反应钩子棉绒:

React Hook React.useMemo 有一个不必要的依赖:'myMap'。排除它或删除依赖数组。像“myMap”这样的外部范围值不是有效的依赖项,因为改变它们不会重新渲染组件。(react-hooks/exhaustive-deps)

所以你应该没问题:

const myValue = useMemo((): string[] => {
  if (someCondition) {
    return myMap?.field[subfieldId] || null
  } else {
    // ...
  }
}, [subfieldId]);
于 2020-11-18T03:57:16.693 回答