[英]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.