ES6中React Class定义方法的两种方式有什么区别

IT技术 javascript reactjs arrow-functions ecmascript-next class-fields
2021-05-14 21:52:18

我在 ES6 React 代码中看到了很多

class Foo extends React.Component {
  bar = () => {
    console.log("bar")
  }

  baz() {
    console.log("baz")
  }
}

好像他们都定义方法barbazFoo,但他们如何不同。

3个回答

声明的不同之处在于函数的编写方式和contextof this,

在第一个语法中

bar = () => {
    console.log("bar")
  }

该函数是使用Arrow function语法编写的

箭头函数没有自己的this使用this封闭执行context因此this,此函数内的关键字将指代React class

然而第二个声明

baz() {
    console.log("baz") 
}

是一个简单的函数,this keyword在这个函数中指的是函数本身的上下文。

因此,当您尝试访问 React 类属性/函数时,this.state或者this.setState您将在第二种情况下收到错误(如果您没有为此函数在其他任何地方使用绑定(示例构造函数)),而它会在第一种情况下工作,因为 for箭头函数,this在函数体内和在函数体外意味着相同的东西。这意味着如果您在零部件的自定义函数中使用箭头的功能,他们可以使用this,并this.setState没有惊喜。

检查这个答案,了解为什么需要在 React 类中绑定函数

以前的答案是绝对正确的,这就是为什么您希望在 React 类中使用箭头函数的原因。

我只是想指出一个微妙的区别,这是它们在课堂上使用的潜在陷阱,以避免出现意外……

定义在类上的箭头函数作为一个属性添加到实例中,恰好是一个函数,而不定义为箭头函数会将函数作为方法添加到类的原型中

在永远不会扩展的 React 组件中,这很好,但是如果出现您想要子类化组件的情况,您将无法覆盖期望能够通过 调用基类的箭头函数super,您只能覆盖它整体而言

class Button extends React.PureComponent {

    // class method - overridable in subclass
    pressMethod: function(): void {
      console.log('beep')
    }

    // instance property functions - only overwriteable in subclass
    pressArrow = (): void => {
      console.log('boop')
    }

    pressArrowTwo = (): void => {
      console.log('blip')
    }

  }


  class BigRedButton extends Button {

    // class method - overides subclass one, 
    // can call superclass method via `super`
    pressMethod: function(): void {
      super.pressMethod() // prints 'beep' to console
      console.log('BOOOOOOOOM!!!')
    }

    // instance property function
    // cannot call superclass via `super` as lambda's have no prototype
    pressArrow = (): void => {
      super.pressArrow() // TypeError - not a function
      console.log('BOOOOOOOOM!!!')
    }

    // completely overwrites instance property of same name in subclass
    // doesn't try to access prototype so won't error but is limited
    pressArrowTwo = (): void => {
      console.log('BOOOOOOOOM')
    }

  }

为简单起见,两者是相等的:

  1. bar = () => { ... }
  2. this.bar =this.bar.bind(this)