reactjs - react hook useEffect infinite loop despite dependency list
问题描述
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
}
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.
解决方案
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
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
}
推荐阅读
- java - 具有已定义键的 Java 对象数组
- python-3.x - 如何在 python 3.7 中的 paramiko 中维护会话
- modal-dialog - 即使导入并声明了Angular 8,也无法从模块中导出组件
- react-native - React Navigation 5 - 带有自定义标题的本机 Stack Navigator,它有一个搜索栏
- postgresql - 可重复使用的唯一行 ID
- android - 如何仅在颤动中仅给出年份中的日期来获取日期
- node.js - 如何使用“npm list”命令中的日志写入 txt 文件?
- powershell - jira rest-api 附加文件以使用 powershell 发出
- python - 如何用来自同一数据帧的相邻行值替换布尔值
- thread-safety - apache flink TimerService 回调和 KeyedProcessFunction.processElement 线程安全吗