尽管依赖列表,react hook useEffect 无限循环 [英] react hook useEffect infinite loop despite dependency list
问题描述
我一直在尝试了解钩子,特别是 useEffect 及其依赖项列表,但出于某种原因,以下代码一直在无休止地运行.我发现了 this 非常相关的问题,但无法制作我的代码按照那里的建议工作.这是有问题的代码,您可能需要启用浏览器控制台才能看到循环.
I've been trying to get my head around hooks, in particular useEffect and its dependency list, but for some reason, the following code keeps running endlessly. I've found this very relevant question but haven't been able to make my code work following the suggestion there. Here is the buggy code, you may have to enable your browser console to see the loop.
// 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 次空值,然后无休止地打印 42好像是两批的.我很新,所以任何帮助将不胜感激.
In essence, I have a state (account
) which is updated using a fetch (fake in this case). While the account has not been fetched yet, account.loaded
is set to false. This ensures that when useFetchBalance
is called it will not fetch the balance. I'd expect the console to log initially a null value, and 6 seconds later (3 for fetching the account and 3 for fetching the balance), to log 42. However, it first prints null 3 times and then prints 42 endlessly in what seems to be batches of two. I am very new to react so any help would be greatly appreciated.
推荐答案
App
组件中的 my_fetch
组件在每次重新渲染时都会触发,当 时调用一次>App
使用带有空依赖项数组的 useEffect
挂载,这将确保 my_fetch
在组件挂载时只运行一次,而不是在每次重新渲染时运行
Your my_fetch
inside App
component keeps firing on every re-render, call it once when App
mounts using useEffect
with empty dependencies array, this will make sure my_fetch
is going to run only once when the component mounts and not on every re-render
不要忘记 React 函数式组件毕竟是函数,所以每次重新渲染时都会执行该函数,这就是为什么我们需要使用 React 提供给我们的辅助函数
Don't forget that React functional components are after all functions, so on every re-render the function will get executed, this is why we need to use the helper functions React provide us
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
}
这篇关于尽管依赖列表,react hook useEffect 无限循环的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!