使用React 16.8.6(在之前的版本16.8.3上很好),当我试图阻止fetch请求上的无限循环时,我得到了这个错误:

./src/components/BusinessesList.js
Line 51:  React Hook useEffect has a missing dependency: 'fetchBusinesses'.
Either include it or remove the dependency array  react-hooks/exhaustive-deps

我一直无法找到一个解决办法来停止这个无限循环。我想远离使用useReducer()。我确实找到了关于'筋疲力尽-deps' lint规则#14920的讨论[ESLint]反馈,其中一个可能的解决方案是,如果你认为你知道你在做什么,你可以总是// ESLint - disabled -next-line react-hooks/详尽-deps。我对我正在做的事情没有信心,所以我还没有尝试实现它。

我有这个当前的设置,React钩子useEffect连续运行永远/无限循环,唯一的评论是关于useCallback(),我不熟悉。

我目前如何使用useEffect()(我只想在开始时运行一次,类似componentDidMount()):

useEffect(() => {
    fetchBusinesses();
  }, []);
const fetchBusinesses = () => {
    return fetch("theURL", {method: "GET"}
    )
      .then(res => normalizeResponseErrors(res))
      .then(res => {
        return res.json();
      })
      .then(rcvdBusinesses => {
        // some stuff
      })
      .catch(err => {
        // some error handling
      });
  };

当前回答

在项目中禁用此警告

将这个"react-hooks/ exhaustion -deps": "off"添加到.eslintrc.js文件中

其他回答

如果您没有在除效果之外的任何地方使用fetchBusinesses方法,您可以简单地将其移动到效果中并避免警告

useEffect(() => {
    const fetchBusinesses = () => {
       return fetch("theURL", {method: "GET"}
    )
      .then(res => normalizeResponseErrors(res))
      .then(res => {
        return res.json();
      })
      .then(rcvdBusinesses => {
        // some stuff
      })
      .catch(err => {
        // some error handling
      });
  };
  fetchBusinesses();
}, []);

然而,如果您在效果之外使用fetchBusinesses,则必须注意两件事

是否有任何问题,你不传递fetchBusinesses作为方法时,它被使用在装载与它的封闭? 你的方法是否依赖于它从封闭包中接收到的一些变量?你不是这样的。 在每次渲染时,fetchBusinesses将被重新创建,因此将它传递给useEffect将会导致问题。因此,如果要将fetchBusinesses传递给依赖数组,首先必须记住它。

总而言之,我想说的是,如果你在useEffect之外使用fetchBusinesses,你可以使用// eslint-disable-next-line react-hooks/ -deps禁用该规则,否则你可以将方法移动到useEffect内部

要禁用规则,可以这样编写

useEffect(() => {
   // other code
   ...
 
   // eslint-disable-next-line react-hooks/exhaustive-deps
}, []) 

你正在使用useEffect,当你这样做的时候,你经常会想要使用一些变量作为你的组件中的道具或状态。

eslint中有一个规则,它希望你引用useEffect依赖数组中任何不同的道具或状态块。这是控制何时执行useEffect的数组。该规则希望看到它列在数组中,数组决定何时重新运行useEffect函数。

因此,您需要添加[fetchBusinesses],这样警告就会消失。

为什么这个规则要我们把它写在这里?

在某些情况下,使用useEffect而没有正确列出数组内的所有状态和道具,可能会导致奇怪且难以调试的问题。

因此,这条规则有助于避免使用useEffect可能出现的那些难以理解的问题。

现在,任意添加到该数组也会导致错误。所以无论哪种方式,你都遇到了必须解决的bug。根据你的评论,似乎为你解决了这个问题,但我想进一步调查,看看你是否有机会在你的网络选项卡在Chrome中添加fetchBusinesses函数到你的useEffect数组后得到第二个GET请求。

这些警告对于查找不一致更新的组件非常有帮助:从依赖项列表中省略函数是否安全?

然而,如果你想在你的项目中删除警告,你可以添加到你的ESLint配置:

  {
  "plugins": ["react-hooks"],
  "rules": {
    "react-hooks/exhaustive-deps": 0
    }
  }
const [mount, setMount] = useState(false)
const fetchBusinesses = () => {
   // Function definition
}
useEffect(() => {
   if(!mount) {
      setMount(true);
      fetchBusinesses();
   }
},[fetchBusinesses, mount]);

这个解决方案非常简单,你不需要重写ESLint警告。只需维护一个标志,以检查组件是否已挂载。

搜索关键字以了解有关每个警告的更多信息。 要忽略,在前一行添加// eslint-disable-next-line。

例如:useEffect中使用的函数正在引起警告

useEffect(() => { handleConnectWallet(); }, []);

要忽略警告,我们只需在警告行之前添加“// eslint-disable-next-line”。

useEffect(() => { handleConnectWallet (); / / eslint-disable-next-line },[]);