我一直在努力弄清楚钩子,尤其是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个值。似乎是两个批次。我很新来做出反应,因此我们将不胜感激。
答案 0 :(得分:3)
您在my_fetch
组件内的App
会在每次重新渲染时保持触发状态,当App
使用useEffect
并使用空的依赖项数组进行挂载时调用一次,这将确保{ {1}}仅在组件安装时运行一次,而不在每次重新渲染时运行
别忘了React功能组件是所有功能的一部分,因此每次重新渲染功能都会执行,这就是为什么我们需要使用React提供的辅助功能的原因
my_fetch