使用es6类时,React中的"super()"和"super(props)"有什么区别?

Mis*_*hko 493 ecmascript-6 reactjs

何时重要的propssuper(),为什么?

class MyComponent extends React.Component {
  constructor(props) {
    super(); // or super(props) ?
  }
}
Run Code Online (Sandbox Code Playgroud)

Rob*_*rny 668

只需要传递props给一个原因super():

当您想要this.props在构造函数中访问时.

通过:

class MyComponent extends React.Component {    
    constructor(props) {
        super(props)

        console.log(this.props)
        // -> { icon: 'home', … }
    }
}
Run Code Online (Sandbox Code Playgroud)

不通过:

class MyComponent extends React.Component {    
    constructor(props) {
        super()

        console.log(this.props)
        // -> undefined

        // Props parameter is still available
        console.log(props)
        // -> { icon: 'home', … }
    }

    render() {
        // No difference outside constructor
        console.log(this.props)
        // -> { icon: 'home', … }
    }
}
Run Code Online (Sandbox Code Playgroud)

需要注意的是通过或不通过props,以super没有影响对后来的用途this.props之外constructor.也就是说render,shouldComponentUpdate或事件处理程序始终可以访问它.

索菲·阿尔珀特(Sophie Alpert)对一个类似问题的回答明确地说明了这一点.


文档 - 状态和生命周期,向类添加本地状态,指向第2点 -重新命名:

类组件应该总是调用基础构造函数props.

但是,没有提供任何理由.我们可以推测它要么是因为子类化,要么是为了将来的兼容性.

(感谢@MattBrowne的链接)

  • 也许我只是在这里打开一堆蠕虫,但**为什么_ever_将`props`传递给`super`,正如你所指出的那样,`props`参数就可以在我们的构造函数中使用了**和`this.props`在其他地方都可以使用吗?使用`this.props`而不仅仅是`props`有什么好处?在构造函数中构造`props`是不好的做法?我想我仍然没有看到你需要将`props`传递给'super`的案例,但是我愿意打赌这只是我的无知,哈哈. (22认同)
  • 尽管其他答案获得更多选票,但我认为你是对的.`this.props`是`undefined`,除非传递给`super()`.无论哪种方式,它都不会影响`render()`函数中`this.props`的后期渲染或可用性. (15认同)
  • 如果你使用`super(props)`,你可以在构造函数*中调用使用`this.props`*的方法,比如`this.doStuffUsingThisDotProps()`,而不必将props参数传递给那些方法/函数.我刚刚编写了一个构造函数,根据这个问题的答案,这似乎需要我首先使用`super(props)`. (9认同)
  • 根据React文档,你应该总是将`props`传递给`super()`:https://facebook.github.io/react/docs/state-and-lifecycle.html#adding-local-state-to-一类.我不知道为什么,因为你指出`this.props`可以通过其他方法访问...也许他们推荐这个以便将来兼容,以防React的未来版本可能想用`props做某事`在构造函数中? (7认同)
  • @Rotareti,不,实际上该类的其余部分并不依赖于这个结构,这就是重点.组件通过构造函数参数以不同的方式接收props.因为你将初始道具传递给`super`,所以你在构造函数中引用了它们. (3认同)

Dav*_*ave 54

在这个例子中,您正在扩展React.Component该类,并且根据ES2015规范,子类构造函数在被调用this之前无法使用super(); 另外,ES2015类构造函数必须调用super()它们是否为子类.

class MyComponent extends React.Component {
  constructor() {
    console.log(this); // Reference Error
  }

  render() {
    return <div>Hello {this.props.name}</div>;
  }
}
Run Code Online (Sandbox Code Playgroud)

相比之下:

class MyComponent extends React.Component {
  constructor() {
    super();
    console.log(this); // this logged to console
  }

  render() {
    return <div>Hello {this.props.name}</div>;
  }
}
Run Code Online (Sandbox Code Playgroud)

根据这个优秀的堆栈溢出答案的更多细节

您可能会看到通过扩展React.Component不调用的类而创建的组件示例,super()但您会注意到这些组件没有constructor,因此没有必要.

class MyOtherComponent extends React.Component {
  render() {
    return <div>Hi {this.props.name}</div>;
  }
}
Run Code Online (Sandbox Code Playgroud)

我从一些开发人员那里得到的一点困惑是,那些没有constructor,因此不在super()任何地方调用的组件仍然this.props可以在render()方法中使用.请记住,此规则和此需要创建this绑定constructor仅适用于constructor.

  • 非常感谢您的回答,但它没有回答我原来的问题(`super()`和`super(props)`之间的区别). (15认同)

Nah*_*nde 45

当你传递propssuper道具时,道具被分配给this.看一下以下场景:

constructor(props) {
    super();
    console.log(this.props) //undefined
}
Run Code Online (Sandbox Code Playgroud)

你怎么做:

constructor(props) {
    super(props);
    console.log(this.props) //props will get logged.
}
Run Code Online (Sandbox Code Playgroud)

  • 这个答案是正确的一半,这个例子仅适用于构造函数方法。例如,即使不写 super(props),render 方法下的 this.props 仍然会被赋值并可用。上面提到的唯一原因是在构造函数中使用 this.props 时。 (2认同)

zer*_*kms 11

根据源代码

function ReactComponent(props, context) {
  this.props = props;
  this.context = context;
}
Run Code Online (Sandbox Code Playgroud)

props每次有道具时都必须通过,而不是this.props手动将它们放入.


Alf*_*rez 9

Dan Abramov撰写了有关此主题的文章:

为什么我们要编写超级道具?

其要点是养成通过它避免这种情况的习惯,这很有帮助,说实话,我认为这种情况不太可能发生:

// Inside React
class Component {
  constructor(props) {
    this.props = props;
    // ...
  }
}

// Inside your code
class Button extends React.Component {
  constructor(props) {
    super(); //  We forgot to pass props
    console.log(props);      // ? {}
    console.log(this.props); //  undefined 
  }
  // ...
}
Run Code Online (Sandbox Code Playgroud)


Dan*_*iel 6

constructor()React组件内部实现功能时,super()是必需的。请记住,您的MyComponent组件是从React.Component基类扩展或借用功能。

这个基类具有constructor()自己的功能,其中包含一些代码,可以为我们设置React组件。

当我们constructor()MyComponent类内部定义一个函数时,实质上constructor()是在覆盖或替换React.Component该类内部的函数,但是我们仍然需要确保constructor()仍调用该函数内部的所有设置代码。

因此,为了确保调用React.Componentconstructor()功能,我们调用super(props)super(props)是对父constructor()函数的引用,仅此而已。

我们必须在基于类的组件中super(props)定义constructor()函数的每一次添加。

如果不这样做,我们将看到一条错误消息,要求我们致电super(props)

定义此功能的全部原因constructor()是初始化我们的状态对象。

因此,为了初始化我们的状态对象,在超级调用下面,我要编写:

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

      this.state = {};
   }

  // React says we have to define render()
  render() {
    return <div>Hello world</div>;
  }
};
Run Code Online (Sandbox Code Playgroud)

因此,我们定义了constructor()方法,通过创建JavaScript对象,将属性或键/值对分配给它,将结果分配给来初始化状态对象this.state。当然,现在这只是这里的一个示例,因此我并没有真正为状态对象分配键/值对,它只是一个空对象。


bes*_*noe 5

这是我制作的小提琴:jsfiddle.net。它表明默认情况下 props 不是在构造函数中分配的。据我了解,它们是在方法中分配的React.createElement。因此,仅当超类的构造函数手动分配给super(props)时才应调用。如果你只是扩展调用,则对 props 没有任何作用。也许在 React 的下一个版本中它会改变。propsthis.propsReact.Componentsuper(props)


小智 5

super() 用于调用父构造函数.

super(props)将传递props给父构造函数.

从您的示例中,super(props)将调用作为参数React.Component传入的构造props函数.

有关更多信息super: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/super

  • 是的,这就是它的作用.但为什么*?*当*是React所需的两种形式之一时? (18认同)

VIK*_*HLI 5

在这里,我们不会在构造函数中获取 this,因此它将返回 undefined,但我们将能够在构造函数之外获取 this

\n\n
class MyComponent extends React.Component {\n  constructor() {\n    console.log(this); // Reference Error i.e return undefined\n  }\n\n  render() {\n    return <div>Hello {this.props.name}</div>;\n  }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

如果我们使用 super(),那么我们也可以在构造函数中获取“this”变量

\n\n
class MyComponent extends React.Component {\n  constructor() {\n    super();\n    console.log(this); // this logged to console\n  }\n\n  render() {\n    return <div>Hello {this.props.name}</div>;\n  }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

所以当我们使用 super(); 时 我们将能够获取 this,但 this.props 在构造函数中将是未定义的。但除了构造函数之外,this.props 不会返回 undefined。

\n\n

如果我们使用 super(props),那么我们也可以在构造函数中使用 this.props 值

\n\n

索菲·阿尔珀特的回答

\n\n
\n

如果要在构造函数中使用 this.props,则需要将\n props 传递给 super。否则,\xe2\x80\x99 并不重要,因为 React 在调用构造函数后立即从外部在实例上设置 .props\n 。

\n
\n


小智 5

对于 react 16.6.3版本,我们使用super(props)来初始化 state 元素名称:this.props.name

constructor(props){
    super(props);        
}
state = {
  name:this.props.name 
    //otherwise not defined
};
Run Code Online (Sandbox Code Playgroud)