小编典典

具有箭头功能的事件处理程序如何实现上下文绑定

reactjs

我了解this绑定的一般理论(重要的函数调用站点,隐式,显式绑定等)以及解决React中此绑定问题的方法,因此它始终指向我想要的对象this(在构造函数,箭头函数等),但我正在努力获取内部机制。

看一下这两段代码:

class demo extends React.component {
  goToStore(event) {
    console.log(this)
  }

  render() {
    <button onClick={(e) => this.goToStore(e)}>test</button>
  }
}

class demo extends React.component {
  goToStore(event) {
    console.log(this)
  }

  render() {
    <button onClick={this.goToStore}>test</button>
  }
}

我所知道的是:

  • 在这两个版本中,我们都成功地使用goToStore方法成功,因为方法this内部render()自动(由React绑定)到组件实例
  • 因此,第一个成功了,
  • 第二个失败,因为es6中的类方法未绑定到组件实例,因此this将方法解析为undefined

据我了解,从理论上讲,在第一版中会发生以下情况:

  1. 按钮点击处理程序是一个匿名 箭头 函数,因此,每当我在其中引用this时,它都会this从环境中拾取(本例中为render()
  2. 然后调用goToStore方法,即常规函数。
  3. 因为该调用似乎符合隐式绑定(object.function())的规则,所以object它将成为上下文对象,并且在此类函数调用中,它将用作this
  4. 因此,在goToStore方法内部,按词法拾取该对象(用作上下文对象)将正确解析为组件实例

我觉得这里不是3.和4.,因为那样就适用于2.情况:

<button onClick={this.goToStore}>test</button>

还带有this上下文对象。

在这种特定情况下,逐步发生了什么?


阅读 269

收藏
2020-07-22

共1个答案

小编典典

如MDN文档所述

箭头函数没有它自己的;使用封闭执行上下文的this值

所以你会想到

onClick={(e) => this.goToStore(e)}

作为匿名函数,可以写成

    (e) => { 
         return this.goToStore(e) 
    }

现在,这里的匿名函数this是指render函数的词法上下文,而后者又是React类实例。

现在

上下文 通常由函数的调用方式决定。当将函数作为对象的方法调用时,会将其设置为调用该方法的对象:

var obj = {
    foo: function() {
        return this;   
    }
};

obj.foo() === obj; // true

使用new运算符调用函数以创建对象的实例时,适用相同的原理。以这种方式调用时,在函数范围内的this值将设置为新创建的实例:

function foo() {
    alert(this);
}

foo() // window
new foo() // foo

当作为未绑定函数调用时,它将默认为浏览器中的全局上下文或窗口对象。

因此,由于在函数this.goToStore() 内部这样调用函数,因此它将引用React组件的上下文。

但是,当您编写时onClick={this.goToStore},不会执行该函数,而是将其引用分配给onClick函数,该函数随后会调用它,导致this该函数在函数内部在window对象的上下文上运行时未定义

现在即使onClick={(e) => this.goToStore(e)}可以使用,只要调用render就会创建一个新的函数实例。在您的情况下,只需使用箭头函数语法创建函数goToStore即可避免这种情况。

goToStore = (e) => {

}

检查文档以获取更多详细信息 this

2020-07-22