繁体   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