使用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
      });
  };

当前回答

似乎在组件中声明了fetchBusinesses函数。 这意味着在每次渲染中,它都声明了触发钩子的新函数。

有两种方法可以解决这个问题。

将fetchBusinesses函数声明移出组件。 使用useCallback钩子包装fetchBusinesses函数。

第一种选择更可取。

其他回答

在我的例子中,它对我的局部变量组织有这个警告,当我把组织放在依赖数组中时,useEffect将获取无限。因此,如果你有一些像我这样的问题,使用useEffect和依赖数组并拆分:

因为如果您有多个修改状态的API调用,它会多次调用useEffect。

来自:

  const { organization } = useSelector(withOrganization)
  const dispatch = useDispatch()

  useEffect(() => {
    dispatch(getOrganization({}))
    dispatch(getSettings({}))
    dispatch(getMembers({}))
  }, [dispatch, organization])

To:

  const { organization } = useSelector(withOrganization)
  const dispatch = useDispatch()

  useEffect(() => {
    dispatch(getOrganization({}))
    dispatch(getSettings({}))
  }, [dispatch, organization])

  useEffect(() => {
    dispatch(getMembers({}))
  }, [dispatch])

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

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

  {
  "plugins": ["react-hooks"],
  "rules": {
    "react-hooks/exhaustive-deps": 0
    }
  }
./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

这不是一个JavaScript/React错误,而是一个ESLint (ESLint -plugin- React -hooks)警告。

它告诉你这个钩子依赖于fetchBusinesses函数,所以你应该把它作为一个依赖项传递。

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

如果函数在组件中声明,则可能导致在每次渲染时调用该函数:

const Component = () => {
  /*...*/

  // New function declaration every render
  const fetchBusinesses = () => {
    fetch('/api/businesses/')
      .then(...)
  }

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

  /*...*/
}

因为每次用新的引用重新声明函数时。

正确的做法是:

const Component = () => {
  /*...*/

  // Keep the function reference
  const fetchBusinesses = useCallback(() => {
    fetch('/api/businesses/')
      .then(...)
  }, [/* Additional dependencies */])

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

  /*...*/
}

或者只是在useEffect中定义函数。

更多:[ESLint]关于'枯竭-deps' lint规则#14920的反馈

下一行禁用ESLint即可;

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

通过这种方式,您使用它就像使用组件挂载(调用一次)一样。

更新

or

const fetchBusinesses = useCallback(() => {
 // Your logic in here
 }, [someDeps])

useEffect(() => {
   fetchBusinesses();
// No need to skip the ESLint warning
}, [fetchBusinesses]);

fetchBusinesses将在每次someDeps更改时被调用。

这不是一个特定于问题用例的答案,而是更普遍的情况,并涵盖了useEffect或提取和导入不工作的情况。 useRef senario:

有时情况是,useEffect应该有一个空数组,你仍然想在useEffect部分的状态中使用,但仍然不想将它们作为依赖注入,你也可以尝试useCallback,现在react抱怨useCallback的依赖,你卡住了。 在这种情况下,在某些情况下可以使用useRef。例如:

const locationRef = useRef(location);
useEffect(()=>{
const qs = locationRef.current.search
...
},[])

在使用这种技术时,您应该小心,并注意useRef不会激活渲染进程。