[英]Async function into useEffect fetches data after componet rendering
我使用onGetAccount
function 來獲取登錄用戶的地址:
const [userWalletInfo, setUserWalletInfo] = useState()
async function onGetAccount() {
const account = await client.api.asset.getAccount();
return account;
}
useEffect(() => {
async function fetchUserWalletInfo() {
const address = await onGetAccount();
setUserWalletInfo({
address: address,
});
}
fetchUserWalletInfo();
}, []);
通過這樣做,我可以訪問userWalletInfo.address
。
問題是,如果我加載組件,然后(我的意思是當組件在本地主機上運行時,我在 VSCode 中編輯代碼,我這樣做是為了了解地址是否設置正確)我編輯js。 文件添加:
<div> {userWalletInfo.address} </div>
它正確顯示用戶地址,但如果我刷新頁面,我會得到“ TypeError: Cannot read property 'address' of undefined ”。
由此我推斷頁面是在fetchUserWalletInfo()
用完之前呈現的。
將您的 div 更改為僅在userWalletInfo
具有地址時顯示,這將避免渲染 function 嘗試訪問未定義的 object 上的屬性。
<div> {userWalletInfo && userWalletInfo.address} </div>
更多細節:
一開始userWalletInfo
是未定義的,因此嘗試訪問其地址將導致您遇到的錯誤。
渲染 function 在userWalletInfo
中存在填充值之前被調用(即您的 div),因為填充發生在異步調用上,並且 React 渲染嘗試渲染組件而不管后台可能發生的異步調用。
提供的解決方案有效,因為它在嘗試顯示userWalletInfo
時提供了額外的謹慎,它只會在未定義userWalletInfo
時嘗試訪問userWalletInfo
地址,從而解決了在填充值之前呈現 function 的失敗。
“TypeError:無法讀取未定義的屬性‘地址’”。
上面的錯誤信息本質上意味着他userWalletInfo
object is undefined
並且undefined
上沒有address
屬性。
userWalletInfo
未定義的原因是因為您使用異步 function 獲取它,這意味着當您的 render() 第一次執行時, userWalletInfo
的值仍然是undefined
。
為什么在初始渲染時未定義 userWalletInfo?
Because, although you might've made the async function call already, the async functions are not executed on the Javascript main thread, instead they are sent to a WEB API environment as soon as the line of code containing the async function call is executed.
但是,異步 function 調用之外的代碼仍然是同步的,這意味着它將執行而不是等待異步調用完成並返回數據。
現在,為了不再出現此錯誤,您需要做的就是有一個條件語句。 即,在嘗試檢索要在 DOM 上顯示的address
屬性之前,您需要檢查userWalletInfo
object 是否存在。
您可以通過多種方式做到這一點:
?
像這樣: userWalletInfo?.address
(這就像一個 if 語句。但是這是 ES 2020 語法,因此如果您想支持舊瀏覽器,則需要 polyfill)。Short-circuiting
。userWalletInfo
默認為空 object。 const [userWalletInfo] = useState({})
。 效果類似於可選鏈接,因為它可以防止訪問undefined
運行時錯誤的屬性。如果您想了解有關 Javascript 事件循環和異步 function 調用如何工作的更多詳細信息,請從此處閱讀我的答案:異步調用、事件循環和回調隊列如何工作。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.