何时将 props
传递给 super()
很重要,为什么?
class MyComponent extends React.Component {
constructor(props) {
super(); // or super(props) ?
}
}
需要将 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
对以后在 constructor
之外的 this.props
的使用没有影响。即 render
、shouldComponentUpdate
或事件处理程序始终 可以访问它。
这在 Sophie Alpert 的一个类似问题的 answer 中明确表示。
文档—State and Lifecycle, Adding Local State to a Class, point 2—建议:
类组件应始终使用 props 调用基本构造函数。
但是,没有提供任何理由。我们可以推测它要么是因为子类化,要么是为了未来的兼容性。
(感谢@MattBrowne 提供链接)
在此示例中,您正在扩展 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
类创建的组件示例,但您会注意到这些组件没有 constructor
,因此没有必要。
class MyOtherComponent extends React.Component {
render() {
return <div>Hi {this.props.name}</div>;
}
}
我从与我交谈过的一些开发人员那里看到的一个困惑是,没有 constructor
并因此不在任何地方调用 super()
的组件在 render()
方法中仍然有可用的 this.props
。请记住,此规则以及为 constructor
创建 this
绑定的需要仅适用于 constructor
。
super()
和 super(props)
之间的区别)。
当您将 props
传递给 super
时,道具将分配给 this
。看看下面的场景:
constructor(props) {
super();
console.log(this.props) //undefined
}
当你这样做时:
constructor(props) {
super(props);
console.log(this.props) //props will get logged.
}
在 React 组件中实现 constructor()
函数时,super()
是必需的。请记住,您的 MyComponent
组件正在扩展或借用 React.Component
基类的功能。
这个基类有自己的 constructor()
函数,其中包含一些代码,用于为我们设置 React 组件。
当我们在 MyComponent
类中定义一个 constructor()
函数时,我们实质上是覆盖或替换了 React.Component
类中的 constructor()
函数,但我们仍然需要确保该类中的所有设置代码constructor()
函数仍会被调用。
因此,为了确保调用 React.Component
的 constructor()
函数,我们调用 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
。当然,这只是一个例子,所以我并没有真正为状态对象分配键/值对,它只是一个空对象。
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
}
// ...
}
function ReactComponent(props, context) {
this.props = props;
this.context = context;
}
每次有道具时都必须通过 props
并且不要手动将它们放入 this.props
中。
this.props = props
和 super(props)
是同一个东西?
this.props
——不管在构造函数中做了什么。
super()
用于调用父构造函数。
super(props)
会将 props
传递给父构造函数。
在您的示例中,super(props)
将调用 props
作为参数传入的 React.Component
构造函数。
关于 super
的更多信息:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/super
对于 React 16.6.3 版本,我们使用 super(props) 来初始化状态元素名称:this.props.name
constructor(props){
super(props);
}
state = {
name:this.props.name
//otherwise not defined
};
在这里,我们不会在构造函数中获取 this,因此它将返回 undefined,但我们将能够在构造函数之外获取 this
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>;
}
}
所以当我们使用 super();我们将能够获取 this 但 this.props 将在构造函数中未定义。但除了构造函数,this.props 不会返回 undefined。
如果我们使用 super(props),那么我们也可以在构造函数中使用 this.props 值
如果要在构造函数中使用 this.props,则需要将 props 传递给 super。否则,没关系,因为 React 在调用构造函数后立即从外部设置实例上的 .props。
这是我制作的小提琴:jsfiddle.net。它表明默认情况下,props 不是在构造函数中分配的。据我了解,它们是在方法 React.createElement
中分配的。因此,只有当超类的构造函数手动将 props
分配给 this.props
时,才应调用 super(props)
。如果您只是扩展 React.Component
,则调用 super(props)
不会对 props 做任何事情。也许它会在下一个版本的 React 中改变。
不定期副业成功案例分享
this.props
是undefined
,除非传递给super()
。无论哪种方式,它都不会影响render()
函数中this.props
的后续呈现或可用性。super
,因此您在构造函数中引用了它们。props
传递给super()
:facebook.github.io/react/docs/…。我不知道为什么,因为正如您指出的那样,this.props
可以通过其他方法访问...也许他们建议这样做是为了将来的兼容性,以防未来版本的 React 可能想要对props
做一些事情构造函数?props
传递给super
,正如您所指出的那样,props
参数就在那里可用于我们在构造函数中使用,而this.props
在其他任何地方都可以使用?使用this.props
而不是仅使用props
有什么好处吗?在构造函数中解构props
是不好的做法吗?我想我仍然没有看到您需要将props
传递给super
的案例,但我敢打赌这只是我的无知,哈。super(props)
,则可以调用使用this.props
in from constructor 的方法,例如this.doStuffUsingThisDotProps()
,而无需将 props 参数传递给这些方法/函数。根据这个问题的答案,我刚刚写了一个构造函数,这似乎需要我首先使用super(props)
。