这是React和ECMAScript6/ECMAScript7结合使用系列文章的第三篇。javascript
下面是全部系列文章章节的连接:html
React类,方法绑定(第三部分)webpack
本篇文章Github源码web
React | JS |
---|---|
![]() |
![]() |
你在看上一篇文章中的CartItem render 方法
中使用{this.increaseQty.bind(this)}
代码时,你确定会以为困惑。gulp
若是咱们尝试将{this.increaseQty.bind(this)}
代码替换成{this.increaseQty}
,咱们将在浏览器控制台中发现以下错误:Uncaught TypeError: Cannot read property 'setState' of undefined
.
这是由于咱们当咱们调用一个用那种方法绑定的方法时,this
不是类它自己,this
未定义。相反,若是在案例中,React.createClass()
全部的方法将会自动绑定对象的实例。这多是一些开发者的直觉。
No autobinding was the decision of React team when they implemented support of ES6 classes for React components. You could find out more about reasons for doing so in this blog post.
当React team
经过ES6
来实现对React 组建的支持时,没有设置自动绑定是React team
的一个决定。在这篇博客中你能发现更多关于为何这么处理的缘由。
如今让咱们来看看在你的JSX案例中,使用ES6类建立的方法的多种调用方法。我所考虑到的多种不一样的方法都在这个GitHub repository。
以前咱们已经见到过:
export default class CartItem extends React.Component { render() { <button onClick={this.increaseQty.bind(this)} className="button success">+</button> } }
当任何ES6的常规方法在方法原型中进行this
绑定时,this指向的是类实例。若是你想了解更多Function.prototype.bind()
,你能够访问这篇MDN博客
此方法是上一个与类构造函数的用法的混合:
export default class CartItem extends React.Component { constructor(props) { super(props); this.increaseQty = this.increaseQty.bind(this); } render() { <button onClick={this.increaseQty} className="button success">+</button> } }
你不要再次在JSX代码的其它地方进行绑定,可是这将增长构造函数中的代码量。
ES6 fat arrow functions preserve this context when they are called. We could use this feature and redefine increaseQty() inside constructor in the following way:
当方法被调用时,ES6 fat arrow functions会保留上下文。咱们能使用这个特征用下面的方法在构造函数中重定义increaseQty()
函数。
export default class CartItem extends React.Component { constructor(props) { super(props); this._increaseQty = () => this.increaseQty(); } render() { <button onClick={_this.increaseQty} className="button success">+</button> } }
另外,你能够使用ES2015+类属性语法和箭头函数:
export default class CartItem extends React.Component { increaseQty = () => this.increaseQty(); render() { <button onClick={this.increaseQty} className="button success">+</button> } }
属性初始化和Method 3中的功能同样。
警告: 类属性还不是当前JavaScript标准的一部分。可是你能够在Babel中自由的使用他们。你能够在这篇文章中了解更多类属性的使用。
最近,Babel介绍了Function.prototype.bind()
中::
的使用。在这里我就不深刻细节讲解它工做的原理。有不少其它的小伙伴已经有很完美的解释。你能够Google搜索blog 2015 function bind
了解更多细节。
下面是ES2015+
函数绑定的使用:
export default class CartItem extends React.Component { constructor(props) { super(props); this.increaseQty = ::this.increaseQty; // line above is an equivalent to this.increaseQty = this.increaseQty.bind(this); } render() { <button onClick={this.increaseQty} className="button success">+</button> } }
强调:这个特性是高度的实验,使用它你得本身承担风险。
You also have a possibility to use ES2015+ function bind syntax directly in your JSX without touching constructor. It will look like:
你也能够直接在非构造函数里面的JSX里面直接使用ES2015+函数绑定。效果以下:
export default class CartItem extends React.Component { render() { <button onClick={::this.increaseQty} className="button success">+</button> } }
很是简洁,惟一的缺点是,这个函数将在每一个后续渲染组件上从新建立。这不是最佳的。更重要的是,若是你使用像PureRenderMixin的东西将会出现。
在这篇文章中,咱们已经发现了多种React组建类方法的绑定方法。
扫码申请加入全栈部落 |
---|
![]() |