简体   繁体   English

使用es6在React中绑定此关键字的3种方式

[英]3 ways of binding this keywords in react using es6

I know there are 3 ways to declare a method within a class. 我知道有3种方法可以在类中声明方法。 I used to use React.create class but I decided to go with the hype where I write in newer syntax - ES6. 我曾经使用React.create类,但是我决定使用我在较新的语法ES6中进行的大肆宣传。

I admit I have little about es6. 我承认我对es6知之甚少。 There are 3 ways of bind this keyword. 绑定此关键字有3种方法。

1. 1。

class myClass extends Components {
    constructor(props){
        super()
        this.doSomething = this.doSomething.bind(this)
    }
    doSomething(){
    }
    render(){
       return(<div onClick={this.doSomething}>click me</div>)
    }
}

2. 2。

class myClass extends Components {
    constructor(props){
        super()
    }
    doSomething(){
    }
    render(){
       return(<div onClick={this.doSomething.bind(this)}>click me</div>)
    }
}

3. 3。

class myClass extends Components {
    constructor(props){
        super()
    }
    doSomething(){
    }
    render(){
       return(<div onClick={e => this.doSomething}>click me</div>)
    }
}

My question is how these different ways of doing things different from each other? 我的问题是,这些不同的做事方式如何彼此不同?

As your question. 作为您的问题。

Method 1 is using function defined in constructor. 方法1 使用构造函数中定义的函数。

This method is a mix of the previous one with usage of class constructor function. 此方法是前一个方法与类构造函数的结合使用。

You don't have to use bind() inside your JSX anymore, but this comes with the cost of increasing the size of constructor code. 您不必再在JSX内部使用bind() ,但这会增加构造函数代码的大小。

Method 2 is using of Function.prototype.bind(). 方法2 使用Function.prototype.bind()。

As any method of ES6 class is plain JavaScript function it inherits bind() from Function prototype. 由于ES6类的任何方法都是普通的JavaScript函数,因此它会从Function原型继承bind() So now when we call increaseQty() inside JSX , this will point to our class instance. 因此,现在当我们在JSX中调用invokeQty increaseQty() ,它将指向我们的类实例。 You could read more about Function.prototype.bind() in this MDN article . 您可以在此MDN文章中阅读有关Function.prototype.bind()更多信息。

Method 3 is using fat arrow function and constructor. 方法3 使用胖箭头函数和构造函数。

ES6 fat arrow functions preserve this context when they are called. ES6粗箭头函数在调用时会保留此上下文。 We could use this feature and redefine doSomething() inside the constructor. 我们可以使用此功能并在构造函数中重新定义doSomething()

these are examples of scoped functions. 这些是范围函数的示例。

https://ariya.io/2013/05/es6-and-block-scope

so for the first instance 所以首先

onClick={this.doSomething}

onClick is outside scope from the class. onClick在类的范围之外。 so binding is required. 因此需要绑定。 so calling this inside it will refer to the React element (div) 因此在内部调用它将引用React元素(div)

second instance 第二审

onClick={this.doSomething.bind(this)}

basically the same. 基本相同。 now you bind this from the caller of the onClick. 现在您绑定this从的onClick的调用者。 which happens to be the class. 碰巧是班级。

third instance 第三审

onClick={e => this.doSomething}

using arrows changes the context of the function, so from this refering to div, it becomes this referring to class 使用箭头转换功能的上下文中,所以从this指的div的,它成为this参照类

bonus instance 奖金实例

doSomething = () => {}

call it like 称它为

onClick={ this.doSomething }

In short, option 1 binds this in the constructor, so that the binding only happens once for each usage of a component. 总之,选项1结合this在构造,使得装订仅在部件的每个的使用发生一次。 This comes at the expense of having to write a constructor, which might not have otherwise been necessary. 这是以必须编写构造函数为代价的,否则可能没有必要。

Option 2 and 3 achieve the same thing using different syntax, creating a new function with this bound every time the component is rendered. 选项2和3使用不同的语法实现相同的功能,每次渲染组件时都this边界创建一个新函数。

Your option 3 should actually call the function doSomething , ie e => this.doSomething() . 您的选项3实际上应该调用函数doSomething ,即e => this.doSomething() Personally I would either pass the event e to the function or change e to () to make it clear that the anonymous function wasn't using any parameters. 就我个人而言,我要么将事件e传递给函数,要么将e更改为()以清楚地表明匿名函数未使用任何参数。

The first option is slightly more efficient, as you're not creating a new function on every render but I tend to go with option 3 because it looks nicer and I've never noticed any real performance problems with it. 第一个选项效率更高一些,因为您不会在每个渲染上都创建一个新函数,但是我倾向于使用选项3,因为它看起来更好,而且我从未注意到它的任何实际性能问题。 Up to you. 由你决定。


As an aside, if you use createClass then React handles the binding of this in your methods for you, which is something to consider when evaluating which method to go with. createClass ,如果您使用createClass那么React将在您的方法中为您处理this方法的绑定,这是在评估使用哪种方法时要考虑的事项。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM