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

IT技术 reactjs ecmascript-6
2021-04-20 23:35:27

什么时候传递props很重要super(),为什么?

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

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

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

通过:

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

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

这在 Sophie Alpert对类似问题回答中明确表示


文档——状态和生命周期,将本地状态添加到类,第 2 点——推荐:

类组件应始终使用props.

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

(感谢@MattBrowne 提供链接)

根据 React 文档,您应该始终传递propssuper()facebook.github.io/react/docs/...我不知道为什么,因为正如您指出的那样this.props,无论哪种方式都可以通过其他方法访问……也许他们建议这样做是为了将来的兼容性,以防将来的 React 版本可能想要props在构造函数中做一些事情
2021-05-21 23:35:27
@Rotareti,不,实际上课程的其余部分不依赖于这个构造,这就是重点。组件通过与构造函数参数不同的方式接收道具。并且由于您将初始道具传递给super,因此您可以在构造函数中引用它们。
2021-05-26 23:35:27
如果使用super(props),则可以调用this.props 在构造函数中使用的方法,例如this.doStuffUsingThisDotProps(),而无需将 props 参数传递给这些方法/函数。super(props)根据this question的答案,我刚刚编写了一个构造函数来执行此操作,这似乎需要我先使用
2021-05-29 23:35:27
我认为您是对的,尽管其他答案获得了更多选票。this.propsundefined,除非传递给super()无论哪种方式,它都不会影响函数this.props中的后续渲染或可用性render()
2021-06-04 23:35:27
也许我只是打开一罐蠕虫在这里,但为什么永远传递propssuper时,正如你所指出,该props参数是正确的有可供我们在构造函数中使用,并且this.props工作在其他地方?使用this.propsover just有什么好处props吗?props在构造函数中解构是不好的做法吗?我想我仍然没有看到你需要传递props给 的情况super,但我敢打赌这只是我的无知,哈。
2021-06-13 23:35:27

在此示例中,您正在扩展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>;
  }
}

相比之下:

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

  render() {
    return <div>Hello {this.props.name}</div>;
  }
}

根据这个优秀的堆栈溢出答案提供更多详细信息

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

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

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

非常感谢您的回答,但它并没有回答我原来的问题(super()之间的区别super(props))。
2021-05-31 23:35:27

当您传递props给 时super,props将被分配给this看看下面的场景:

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

你怎么做:

constructor(props) {
    super(props);
    console.log(this.props) //props will get logged.
}
这个答案对了一半,这个例子只针对构造函数方法。比如,即使不写super(props),render方法下的this.props还是会被赋值和可用的。上面提到的唯一原因是在构造函数中使用 this.props 时。
2021-05-22 23:35:27
列表中的最佳答案。
2021-06-12 23:35:27

Dan Abramov 写了一篇关于这个主题的文章:

我们为什么要写超级(props)?

它的要点是养​​成传递的习惯以避免这种情况是有帮助的,老实说,我认为这不太可能发生:

// 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 
  }
  // ...
}

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()函数的全部原因是为了初始化我们的状态对象。

所以为了初始化我们的状态对象,在 super 调用下面我要写:

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现在当然这只是一个例子,所以我并没有真正为状态对象分配一个键/值对,它只是一个空对象。