在 Promise 的 Catch 块中访问“this”
介绍
Promises 是 JavaScript 编程语言的革命性补充。在 Promises 出现之前,需要将回调传递给函数调用才能对异步控制流进行建模。Promises 为您提供了一种更易读、更易于维护的方式来管理 React 应用中的异步操作。Promise提供的then和catch函数使您能够异步链接函数并处理错误。但是,在范围和this关键字方面,在 React 组件中使用 Promise 可能会造成混淆。在 JavaScript 中,this关键字允许您访问周围词法范围的上下文对象。在本指南中,您将学习如何确保您的 promise catch块在 React 组件中使用正确的上下文,以便您可以通过this轻松访问组件属性。
让我们开始吧!
绑定组件范围
首先,问题来了。在 React 组件中使用 Promise 时,你的第一反应可能是这样处理 Promise:
// ... MammalComponent.jsx
fetchMammals() {
return fetch(this.mammalsUrl)
.then(function(response) {
return response.json();
});
}
initMammalsState() {
const mammalJsonPromise = this.fetchMammals();
mammalJsonPromise
.then(function(mammals) {
this.setState({ mammals });
})
.catch(function(error) {
this.error = error;
});
}
// ...
乍一看,这段代码似乎可以工作。它只是使用Fetch API 来获取一些 JSON,然后处理返回的 Promise。如果在catch块中发生错误,它还会在组件本身上设置error属性。但不幸的是,这段代码失败了!如果你使用上面的代码创建一个组件,你可能会看到一个类似于Can't find property <prop-name> of undefined 的错误。这是因为你的 Promise 无法访问正确的this上下文!
解决此问题的第一个方法是使用JavaScript函数原型上提供的bind函数。bind函数允许您将this上下文注入您正在使用的函数的范围。下面,您将看到上面的函数经过重构以利用此功能。请注意,甚至组件函数本身也绑定到构造函数中的React 组件的this上下文。
// ... MammalComponent.jsx
constructor(props) {
super(props);
// Bind the 'this' context of the component to our class functions
this.fetchMammals = this.fetchMammals.bind(this);
this.initMammalsState = this.initMammalsState.bind(this);
}
fetchMammals() {
return fetch(this.mammalsUrl)
.then(function(response) {
return response.json();
});
}
initMammalsState() {
const mammalJsonPromise = this.fetchMammals();
mammalJsonPromise
.then(function(mammals) {
this.setState({ mammals });
}.bind(this))
.catch(function(error) {
this.error = error;
}.bind(this));
}
// ...
在上面这个简单的解决方案中,您可以看到如何使用bind函数将 this 的上下文绑定到catch块中,以便组件可以显示错误。这有效……但还有更好的方法!在下一节中,您将看到如何使用箭头函数来大大简化这一过程。
使用箭头函数绑定组件范围
箭头函数不仅仅是一种简洁的函数声明方式。箭头函数还为您隐式绑定了this关键字!在下面的代码中,您将看到我们如何通过箭头函数访问MammalsComponent的error属性。
// ... MammalComponent.jsx
// We don't have to bind these functions anymore!
fetchMammals = () => fetch(this.mammalsUrl).then(response => response.json())
initMammalsState = () => {
const mammalJsonPromise = this.fetchMammals();
mammalJsonPromise
.then(mammals => this.setState({ mammals }))
.catch(error => this.error = error);
}
// ...
哇!看看代码有多简单!此代码不仅有效,而且更简洁、更易于维护。catch块现在可以访问MammalComponent的范围,因此它现在可以设置错误属性。
结论
箭头函数是将 React 组件范围的上下文绑定到组件内的内部函数的最佳方式。以这种方式使用箭头函数可让您有效地访问Promise catch块内的this属性。
上述代码还可以进行一些额外的改进,即使用 async/await 语法。JavaScript 关键字 async 和 await 可以简化承诺的使用,并减少代码库中的嵌套代码量。它还允许您以同步方式对异步代码进行建模。有关更多信息,请查看async/await 语法的文档。
免责声明:本内容来源于第三方作者授权、网友推荐或互联网整理,旨在为广大用户提供学习与参考之用。所有文本和图片版权归原创网站或作者本人所有,其观点并不代表本站立场。如有任何版权侵犯或转载不当之情况,请与我们取得联系,我们将尽快进行相关处理与修改。感谢您的理解与支持!
请先 登录后发表评论 ~