【问题标题】:React Hook useEffect missing deps [duplicate]React Hook useEffect缺少deps [重复]
【发布时间】:2021-02-16 14:04:34
【问题描述】:

我正在使用 useEffect 挂钩并收到编译器错误提示 React Hook useEffect has missing dependencies. Either include them or remove the dependency array react-hooks/exhaustive-deps

这两个功能都这么说。我想知道在这种情况下如何使用 useCallBack 挂钩。我没有太多运气找到任何东西。任何摆脱这些编译器警告的帮助都将得到重视!

【问题讨论】:

    标签: javascript reactjs react-hooks use-effect usecallback


    【解决方案1】:

    我假设您发布的所有代码都在您的 React 组件中。不确定如何使用方法返回的值。从示例代码中看不清楚。

    首先关于添加依赖数组后的第二个错误 - 在每次渲染时都重新声明了两个函数。因此 React 认为它们发生了变化并将重新运行钩子。您必须将 creditsgpa 方法都包装在 useCallback 中,以避免将 data 作为依赖项。

    就我个人而言,我会将这两种方法都重构为纯函数。这意味着他们会将数据作为函数的参数,而不是从上层范围获取。然后,如果您将它们都包装在useCallback 中,它们将永远不会改变,因为不会有依赖关系。然后,您可以将这两种方法与数据一起添加到useEffect 挂钩依赖项中,一旦数据发生变化,这两个函数都将被计算。结果将与 oyu 将方法包装在 useCallback 中一样。但我认为使用纯函数,代码更容易推理。你有两个方法需要一些参数,一旦数据发生变化,你运行这些方法来重新计算一些变化。

    这就是我重构代码的方式:

    const credits = useCallback((courses) => {
      let credits = 0
      courses.forEach((c) => (
        credits += parseInt(c.courseCredits)
      ))
      if(isNaN(credits)) credits = 0
      return credits
    }, []);   // <- you have no dependencies, so it will be always same function for entire component lifecycle
      
      const gpa = useCallback((courses) => {
        let honorPoints = 0
        let credits = 0
        let cumulativeGpa = 0
        courses.forEach(c => {
          credits += parseInt(c.courseCredits)
          honorPoints += parseFloat(getGradeNumber(c.numericGrade) * c.courseCredits)
          cumulativeGpa = honorPoints / credits
        })
        if(isNaN(cumulativeGpa)) cumulativeGpa = 0
        return cumulativeGpa.toFixed(2)
      }, []);   // <- you have no dependencies, so it will be always same function for entire component lifecycle
    
      useEffect(() => {
        credits(data)
        gpa(data)
      }, [credits, gpa, data]); // <- credits and gpa will never change so the useEffect will run only when data change
    

    【讨论】:

    • +1。由于这些是纯函数,您甚至不需要将它们包装在 useCallback 中或将纯函数作为 useEffect 的依赖项。但是,如果这比问题中发布的内容更多,这将是这样做的方法。
    • 是的,如果它们是没有任何依赖关系的纯函数,最好在组件之外声明它们(然后您也可以在其他组件中重用它们)。然后它们将始终相同,并且不需要在钩子的依赖项中列出。
    【解决方案2】:

    @Tomáš Pustelník 是对的,但我有另一个解决方案给你。例如,您可以禁用 eslint:

      useEffect(() => {
        credits()
        gpa()
        // eslint-disable-line react-hooks/exhaustive-deps
      }, [data]);
    

    【讨论】:

      猜你喜欢
      • 2021-10-16
      • 2021-02-23
      • 2020-10-26
      • 2019-10-24
      • 2020-03-07
      • 2020-02-25
      • 2020-06-11
      • 2020-03-30
      • 2020-12-29
      相关资源
      最近更新 更多