尽管有依赖项列表,但仍会发生反应钩useEffect无限循环

时间:2019-08-24 00:12:45

标签: reactjs react-hooks

我一直在努力弄清楚钩子,尤其是useEffect及其依赖项列表,但是由于某种原因,以下代码不断运行。我发现this是一个非常相关的问题,但未能按照我的建议使我的代码正常工作。这是错误的代码,您可能必须启用浏览器控制台才能看到循环。

// a fake fetch for the sake of the example
function my_fetch(f, delay) {
  setTimeout(f, delay)
}

// if account is not loaded then useEffect should not fetch the balance
function useFetchBalance(account_id, account_loaded) {

  const [balance, setBalance] = useState(null)

  useEffect(() => {
    if (!account_loaded) return; // only fetch if dependency is resolved
    my_fetch(() => setBalance(41 + account_id), 3000)
  }, [account_id, account_loaded])

  return balance
}


function App() {

  const [account, setAccount] = useState({ id: null, loaded: false })
  my_fetch(() => setAccount({ id: 1, loaded: true }), 3000)

  const balance = useFetchBalance(account.id, account.loaded)
  console.log(balance)

  return null
}

从本质上讲,我有一个状态(account),该状态使用获取(在这种情况下为假)进行更新。虽然尚未提取帐户,但account.loaded设置为false。这样可以确保在调用useFetchBalance时不会获取余额。我希望控制台最初记录一个空值,然后在6秒后(3个用于获取帐户,3个用于获取余额)记录到42。但是,它首先打印3次空值,然后无休止地打印42个值。似乎是两个批次。我很新来做出反应,因此我们将不胜感激。

1 个答案:

答案 0 :(得分:3)

您在my_fetch组件内的App会在每次重新渲染时保持触发状态,当App使用useEffect并使用空的依赖项数组进行挂载时调用一次,这将确保{ {1}}仅在组件安装时运行一次,而不在每次重新渲染时运行

别忘了React功能组件是所有功能的一部分,因此每次重新渲染功能都会执行,这就是为什么我们需要使用React提供的辅助功能的原因

my_fetch