簡體   English   中英

異步 function 進入 useEffect 獲取組件渲染后的數據

[英]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 是否存在。

您可以通過多種方式做到這一點:

  1. 有一個簡單的 if 語句
  2. 使用可選的鏈接運算符? 像這樣: userWalletInfo?.address (這就像一個 if 語句。但是這是 ES 2020 語法,因此如果您想支持舊瀏覽器,則需要 polyfill)。
  3. 像用戶@Shimi 在她的回答中提到的那樣使用Short-circuiting
  4. userWalletInfo默認為空 object。 const [userWalletInfo] = useState({}) 效果類似於可選鏈接,因為它可以防止訪問undefined運行時錯誤的屬性。

如果您想了解有關 Javascript 事件循環和異步 function 調用如何工作的更多詳細信息,請從此處閱讀我的答案:異步調用、事件循環和回調隊列如何工作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM