首页 文章

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

提问于
浏览
374

何时将 props 传递给 super() 很重要,为什么?

class MyComponent extends React.Component {
  constructor(props) {
    super(); // or super(props) ?
  }
}

9 回答

  • 516

    当需要将 props 传递给 super() 时,只有一个原因:

    When you want to access this.props in constructor.

    通过:

    class MyComponent extends React.Component {    
        constructor(props) {
            super(props)
    
            console.log(this.props)
            // -> { icon: 'home', … }
        }
    }
    

    不通过:

    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', … }
        }
    }
    

    请注意,在 this.props 之外的 this.props 之后,传递或不传递 propssuper 具有 no effect . 那是 rendershouldComponentUpdate 或事件处理程序 always 可以访问它 .

    在索菲·阿尔珀特的一篇文章中明确地提到了类似的问题 .


    文档 - State and Lifecycle, Adding Local State to a Class, point 2 -recommends:

    类组件应始终使用props调用基础构造函数 .

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

    (感谢@MattBrowne的链接)

  • 3

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

    class MyComponent extends React.Component {
      constructor() {
        console.log(this); // Reference Error
      }
    
      render() {
        return <div>Hello {this.props.name}</div>;
      }
    }
    

    相比之下:

    class MyComponent extends React.Component {
      constructor() {
        super();
        console.log(this); // this logged to console
      }
    
      render() {
        return <div>Hello {this.props.name}</div>;
      }
    }
    

    根据this excellent stack overflow answer更多细节

    您可能会看到通过扩展不调用 super()React.Component 类创建的组件示例,但您'll notice these don'有一个 constructor ,因此没有必要这样做 .

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

    我所说的一个混淆点是,没有 constructor 且因此不在任何地方调用 super() 的组件仍然在 render() 方法中可用 this.props . 请记住,此规则以及为 constructor 创建 this 绑定的需要仅适用于 constructor .

  • 10

    props 传递给 super 时,道具将分配给 this . 请看下面的场景:

    constructor(props) {
        super();
        console.log(this.props) //undefined
    }
    

    你怎么做:

    constructor(props) {
        super(props);
        console.log(this.props) //props will get logged.
    }
    
  • 46

    根据source code

    function ReactComponent(props, context) {
      this.props = props;
      this.context = context;
    }
    

    每次有道具时都必须通过 props 并且不要手动将它们放入 this.props .

  • 32

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

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

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

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

  • 0

    这是我制作的小提琴:https://jsfiddle.net/beshanoe/zpxbLw4j/1/ . 它显示默认情况下不在构造函数中分配道具 . 据我了解,他们的方法是 React.createElement . 因此,只有当超类的构造函数手动将 props 指向 this.props 时才应调用 super(props) . 如果你只是扩展 React.Component 调用 super(props) 将无法使用道具 . 也许它将在React的下一个版本中进行更改 .

  • 1

    在React组件中实现 constructor() 函数时,需要 super() . 请记住, MyComponent 组件正在扩展或借用 React.Component 基类的功能 .

    这个基类有一个自己的 constructor() 函数,里面有一些代码,为我们设置我们的React组件 .

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

    因此,为了确保调用 React.Componentconstructor() 函数,我们调用 super(props) . super(props) 是对父母 constructor() 函数的引用,就是这样 .

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

    如果我们不这样做,我们会看到一个错误,说我们必须调用 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>;
      }
    };
    

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

  • 0

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

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

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

    class MyComponent extends React.Component {
      constructor() {
        super();
        console.log(this); // this logged to console
      }
    
      render() {
        return <div>Hello {this.props.name}</div>;
      }
    }
    

    So when we are using super(); we will be able to fetch this but this.props will be undefined in the constructor. But other than constructor, this.props will not return undefined.

    If we use super(props), then we can use this.props value inside the constructor as well

    Sophie Alpert's Answer

    如果要在构造函数中使用this.props,则需要将props传递给super . 否则,它无关紧要,因为React在调用构造函数后立即从外部设置.props .

  • 4

    对于反应版本16.6.3,我们使用super(props)初始化状态元素 name : this.props.name

    constructor(props){
        super(props);        
    }
    state = {
        name:this.props.name 
          //otherwise not defined
      };
    

相关问题