【问题标题】:react hook useEffect infinite loop despite dependency list反应钩子useEffect无限循环,尽管依赖列表
【发布时间】:2019-08-24 00:12:45
【问题描述】:

我一直试图了解钩子,特别是 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),它使用 fetch 更新(在这种情况下是假的)。虽然尚未提取帐户,但 account.loaded 设置为 false。这确保了当useFetchBalance 被调用时,它不会获取余额。我希望控制台最初记录一个空值,然后在 6 秒后(3 用于获取帐户,3 用于获取余额)记录 42。但是,它首先打印 3 次 null,然后在什么情况下无休止地打印 42好像是两批的。我很新的反应所以任何帮助将不胜感激。

【问题讨论】:

  • useEffect 中无意中生成调用 fetch 的无限循环非常非常容易,除非您只运行一次(即空数组作为依赖项)。不要难过,恕我直言useEffect 确实是所有 React 中最容易出错的 API。别忘了你总是可以用生命周期方法编写类组件,你不必使用钩子(尽管其余的都很棒)。

标签: reactjs react-hooks


【解决方案1】:

App 中的 my_fetch 组件在每次重新渲染时都会触发,当 App 使用带有空依赖项数组的 useEffect 挂载时调用一次,这将确保 my_fetch 只运行一次当组件挂载而不是每次重新渲染时

别忘了 React 函数式组件毕竟是函数,所以每次重新渲染时函数都会被执行,这就是为什么我们需要使用 React 提供的辅助函数

function App() {
  const [account, setAccount] = useState({ id: null, loaded: false })
  const balance = useFetchBalance(account.id, account.loaded)

  useEffect(() => {
    my_fetch(() => setAccount({ id: 1, loaded: true }), 3000)
  }, [])

  return null
}

【讨论】:

    猜你喜欢
    • 2021-04-10
    • 2020-01-11
    • 1970-01-01
    • 2020-02-26
    • 2020-10-27
    • 1970-01-01
    • 2021-09-27
    • 2021-01-28
    相关资源
    最近更新 更多