React Hook useEffect缺少依赖项。包括它们或删除依赖项数组

时间:2020-04-07 16:39:53

标签: reactjs

我正在制作一个React App,并且收到了这个警告。当组件安装时,我试图进行两个API调用:

useEffect(() => {
  getWebsites();
  loadUserRatings();
}, []);

这就是为什么我有一个空数组的原因,因为我想在安装组件时只调用一次。但是我仍然收到警告,该如何解决?

使用react redux的connect将这两个函数传递给组件,整个组件如下所示:

const Wrapper = (props) => {
  const { getWebsites, loadUserRatings } = props;

  useEffect(() => {
    getWebsites();
    loadUserRatings();
  }, []);

  return (
    <>
      <Header />
      <Websites />
      <Sync />
    </>
  );
};

3 个答案:

答案 0 :(得分:6)

由于您很可能不会在运行时修改函数定义,因此可以将getWebsitesloadUserRatings添加到依赖项数组。

  useEffect(() => {
    getWebsites();
    loadUserRatings();
  }, [getWebsites, loadUserRatings]);

请注意,useEffectgetWebsites发生更改时,loadUserRatings中的代码将运行。如果没有正确记住这两个功能,则会发生这种情况。

防止这种情况的一种好方法是使用useCallback钩子在父组件中对其进行记忆,然后将其传递给Wrapper组件。

答案 1 :(得分:1)

以我的经验,通常不会像这样通过props传递未存储的功能。

// don't do this

<Wrapper
  getWebsites={() => fetchJson('websites').then(setWebsites)}
  loadUserRatings={() => fetchJson('ratings').then(setUserRatings)}
/>

如果正确地记住了它们(使用像useCallback()这样的钩子,或者通过在任何组件之外定义),则可以安全地将它们传递到deps的{​​{1}}行为上的任何差异。这是解决上述情况的示例。*

useEffect()

* // do this const fetchJson = (...args) => fetch(...args).then(res => res.json()); const Parent = () => { const [websites, setWebsites] = useState([]); const [userRatings, setUserRatings] = useState({}); // useCallback creates a memoized reference const getWebsites = useCallback( () => fetchJson('websites').then(setWebsites), [setWebsites] ); const loadUserRatings = useCallback( () => fetchJson('ratings').then(setUserRatings), [setUserRatings] ); ... <Wrapper getWebsites={getWebsites} loadUserRatings={loadUserRatings} /> 在其返回值中记住分派函数,因此从技术上讲,将useState()作为[]传递给此处的每个deps是安全的,但我相信将调度功能指定为依赖项可以通过明确传达作者的意图来提高清晰度,并且传递它们也没有任何缺点。

Ramesh's answer对于这种情况就足够了。


如果发现遇到第一种情况,则作为最后的选择,可以像这样将useCallback()初始化为组件的状态。

props

答案 2 :(得分:1)

您必须将getWebsitesloadUserRatings添加到useEffect的依赖项中:

useEffect(() => {
  getWebsites();
  loadUserRatings();
}, [getWebsites, loadUserRatings]

需要添加在useEffect钩子外部定义的所有变量,并规定必须在组件主体或自定义钩子中定义它们,这些useEffect()是从参数调用或从参数传递的。无需在组件或自定义钩子外部定义的变量就可以添加到依赖项列表中。 (memoization)这是鲜为人知的rules of hooks之一。


注意:(这对您的情况不起作用,因为您的函数是通过props传递的)您也可以将函数包装在useCallback钩子中,或在{{1}内定义所需​​的变量}如果不想将其自身添加到useEffect钩子的依赖项中,则将其自身钩住。