为什么有些开发人员在React.js中的类中使用构造函数和super?

时间:2019-06-07 22:15:36

标签: reactjs es6-class

我总是在组件中使用此表达式:

class Cart extends Component { }

最近我已经看到很多使用此表达式的代码。

class Cart extends React.Component {
  constructor(props) {
    super(props);
  }
}

为什么?使用构造函数和super的目的是什么? React.Component和Component是否相同? 为什么我们在构造函数和super中传递道具? 我不是在问什么是super和构造函数,我是在问上面两个代码之间的区别以及使用每个代码的好处?

我在线检查了一下,但没有看到任何解释,只是代码示例。

5 个答案:

答案 0 :(得分:1)

丹·阿布拉莫夫mentions on his blog

  

在构造器中使用this后,   称为父构造函数。   JavaScript不允许您使用。

     

JavaScript强制要求,如果要在构造函数中使用this,则必须   必须先致电super

需要调用super(props)才能访问this.props

on this thread所述,在React组件上使用构造函数主要有两个原因:

  
      
  1. 通过将对象分配给this.state来初始化本地状态。
  2.   
  3. 绑定   实例的事件处理程序方法。   如果您不初始化状态并且不绑定方法,则无需为React组件实现构造函数。
  4.   
     

如果您不初始化状态并且不绑定方法,那么您不会   需要为您的React组件实现一个构造函数。

答案 1 :(得分:1)

从reactJS网站复制。

  

如果您不初始化状态并且不绑定方法,那么您就不会   需要为您的React组件实现一个构造函数。

     

React组件的构造函数在挂载之前被调用。   在实现React.Component子类的构造函数时,您可以   应该在其他任何语句之前调用super(props)。除此以外,   this.props将在构造函数中未定义,这可能导致   错误。

     

通常,在React中,构造函数仅用于两个目的:

Initializing local state by assigning an object to this.state.
Binding event handler methods to an instance.
     

您不应在构造函数()中调用setState()。相反,如果您的   组件需要使用本地状态,将初始状态分配给   直接在构造函数中使用this.state:

     

构造函数是唯一应分配此位置的地方。   直。在所有其他方法中,您需要使用this.setState()   代替。

     

避免在广告中引入任何副作用或订阅   构造函数。对于这些用例,请改用componentDidMount()。

https://reactjs.org/docs/react-component.html

这是super()的目的,

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/super

我尝试过通天塔,这就是我得到的。

  

有了构造函数,我得到了这个功能,

class App extends React.Component{
    constructor(props){
     this.state = {}
    }
}

ES5中的相关部分,

var App =
/*#__PURE__*/
function (_React$Component) {
  _inherits(App, _React$Component);

  function App(props) {
    var _this;

    _classCallCheck(this, App);

    _this.state = {};
    return _possibleConstructorReturn(_this);
  }

  return App;
}(React.Component);
  

没有构造函数

class App extends React.Component{
    state = {}
}

ES5代码

var App =
/*#__PURE__*/
function (_React$Component) {
  _inherits(App, _React$Component);

  function App() {
    var _getPrototypeOf2;

    var _temp, _this;

    _classCallCheck(this, App);

    for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
      args[_key] = arguments[_key];
    }

    return _possibleConstructorReturn(_this, (_temp = _this = _possibleConstructorReturn(this, (_getPrototypeOf2 = _getPrototypeOf(App)).call.apply(_getPrototypeOf2, [this].concat(args))), _this.state = {}, _temp));
  }

  return App;
}(React.Component);

答案 2 :(得分:0)

  

为什么?使用构造函数和super的目的是什么?

构造函数和super关键字不是特定于响应的,而是特定于JavaScript的。在JavaScript中搜索继承和“ OOP”以更好地理解继承(例如this medium article)。 super并且继承不仅绑定到JavaScript,许多其他语言也使用它并据此进行解释,例如here很好地说明了如何使用super关键字在Java中。

  

我们为什么要在构造函数和super中传递道具?

选中Why Do We Write super(props)?

  

React.Component和Component是否相同?

是的。在文件的开头部分是一堆import ...语句。对于React.Component,您会发现类似import * as React from "react"import React from "react"的东西。对于Component,您会发现import { Component } from "react"Check the import-documentation from MDN以获得更多信息。

  

我要问的是上面两个代码和使用每个代码的好处之间的区别?

结果没有差异。两种版本的工作原理相同,性能没有(显着)差异。一种版本较短,噪音较小。如果您在构造函数中没有进一步的说明,建议不要使用它。

答案 3 :(得分:0)

构造函数和super都不是特定于React的,甚至不是javascript特定的。它们特定于 OOP 中的继承。

构造函数

构造函数可以称为类中的初始化函数。让我们看一个可以使用构造函数的示例。

class parentClass {
 constructor(){
   this.foo = foo;
   this.bar = bar;
}

function sharedMethod1(){
    print(this.foo);
}

function sharedMethod(){
    print(this.bar)
}
}

object1 = new ParentClass(foo1, bar1);

object1.sharedMethod1() // this will print foo1;
object1.sharedMethod2() // this will print bar1;

object2 = new ParentClass(foo2, bar2);
object2.sharedMethod1() // this will print foo2;
object2.sharedMethod2() // this will print bar2;

当需要为成员变量/函数创建具有不同值的类的多个实例时,我们将使用构造函数。

超级

super关键字也用于继承。在继承中,从父类扩展子类时,需要初始化父类的构造函数。 super关键字用于此目的。让我们看下面超级示例。

class ParentClass (){
constructor(){
this.foo = foo;
}
} 

class childClass extends ParentClass(){
super(foo1); // super is used here initialize the constructor of the ParentClass
} 

React也遵循上述相同的原理。 请在https://overreacted.io/why-do-we-write-super-props/

上查看dan abramov的有关构造函数和super的博客文章。

答案 4 :(得分:-1)

  

为什么某些开发人员在其类中使用构造函数和super?

https://www.reactnative.guide/6-conventions-and-code-style/6.4-es7-features.html

唯一的区别是,一个是用ES6编写的,另一个是用ES7编写的。虽然它们都是正确的,但是在ES7中,我们不需要使用构造函数和super,它们构造的更短并且更易于阅读。但是,有些人对此一无所知,或者只是习惯以老式的ES6方式进行操作,或者代码已经过时。我建议使用新的ES7

  
    
      

更新

    
  

通过深入研究这个问题并询问其他人我发现了这个问题

直接在类中定义类属性而不是编写构造函数的选项,以及将函数作为类内部属性而不是方法编写的选项是TC39类字段提案(https://github.com/tc39/proposal-class-fields)的一部分,自2017年以来处于第3阶段(共4阶段)。 在链接的官方页面上,您可以阅读:

“该提案于2017年7月到达Stage 3。自那时以来,人们对各种替代方案进行了广泛的思考和冗长的讨论,包括:

JS Classes 1.1

Reconsideration of "static private"

Additional use of the private keyword

Private Symbols

在考虑每个提案时,TC39的代表深入研究了动机,JS开发人员的反馈以及对语言设计未来的影响。最后,这种思考过程和社区的持续参与导致对该存储库中的提案重新达成共识。基于这一共识,有关此建议的实施正在向前推进。”

我不知道它是否现在将成为ES10(EcmaScript 2019)的一部分,该版本将于7月发布。

但是对于React来说,这无关紧要,因为代码还是可以编译的,并且在TypeScript(用于Angular)中,上述两个功能都已经可用。

此信息归功于Jost S ...