什么时候将props
传递给super()
,为什么这么重要?
class MyComponent extends React.Component {
constructor(props) {
super(); // or super(props) ?
}
}
答案 0 :(得分:608)
只有一个原因需要将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
对render
无影响。这是shouldComponentUpdate
,props
或事件处理程序始终可以访问它。
在一篇索菲·阿尔珀特的answer中明确地提到了类似的问题。
文档 - State and Lifecycle, Adding Local State to a Class, point 2 - 建议:
类组件应始终使用
const
调用基础构造函数。
但是,没有提供任何理由。我们可以推测它要么是因为子类化,要么是为了将来的兼容性。
(感谢@MattBrowne的链接)
答案 1 :(得分:49)
在此示例中,您正在扩展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>;
}
}
根据this excellent stack overflow answer
提供更多详情您可能会看到通过扩展React.Component
类而未调用super()
而创建的组件示例,但您会发现这些组件没有constructor
,因此它不是必要的。
class MyOtherComponent extends React.Component {
render() {
return <div>Hi {this.props.name}</div>;
}
}
我从一些开发人员那里看到的一点困惑是,那些没有constructor
但因此无法在任何地方调用super()
的组件仍然有this.props
render()
方法中提供。请注意,此规则以及为this
创建constructor
绑定的需要仅适用于constructor
。
答案 2 :(得分:39)
当您将props
传递给super
时,道具会被分配到this
。请看下面的场景:
constructor(props) {
super();
console.log(this.props) //undefined
}
你怎么做:
constructor(props) {
super(props);
console.log(this.props) //props will get logged.
}
答案 3 :(得分:11)
function ReactComponent(props, context) {
this.props = props;
this.context = context;
}
每次有道具时都必须通过props
并且不要手动将它们放入this.props
。
答案 4 :(得分:6)
super()
用于调用父构造函数。
super(props)
会将props
传递给父构造函数。
在您的示例中,super(props)
会调用传递React.Component
的{{1}}构造函数作为参数。
有关props
的更多信息:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/super
答案 5 :(得分:6)
Dan Abramov撰写了有关该主题的文章:
https://overreacted.io/why-do-we-write-super-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
}
// ...
}
答案 6 :(得分:4)
这是我做过的小提琴:https://jsfiddle.net/beshanoe/zpxbLw4j/1/。它显示默认情况下不在构造函数中分配道具。据我所知,他们在方法React.createElement
中受到了帮助。因此,只有当超类的构造函数手动将super(props)
传递给props
时,才应调用this.props
。如果您只是延长React.Component
来电super(props)
将无法使用道具。也许它会在React的下一个版本中被更改。
答案 7 :(得分:4)
在React组件中实现constructor()
函数时,super()
是必需的。请记住,您的MyComponent
组件是从React.Component
基类扩展或借用的功能。
该基类本身具有一个constructor()
函数,该函数内部具有一些代码,可以为我们设置React组件。
当我们在constructor()
类中定义MyComponent
函数时,从本质上讲,我们是在重写或替换constructor()
类内部的React.Component
函数,但是我们仍然需要确保此constructor()
函数内部的所有设置代码仍被调用。
因此,为了确保调用React.Component
的{{1}}函数,我们调用constructor()
。 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>;
}
};
方法,通过创建JavaScript对象,为其分配属性或键/值对,并将其结果分配给constructor()
来初始化状态对象。当然,现在这只是这里的一个示例,因此我没有真正为状态对象分配键/值对,它只是一个空对象。
答案 8 :(得分:2)
这里我们不会在构造函数中得到它,所以它将返回未定义,但是我们可以在构造函数之外获取它
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.props将在构造函数中未定义。但是除了构造函数之外,this.props不会返回undefined。
如果我们使用super(props),那么我们也可以在构造函数中使用this.props值
如果要在构造函数中使用this.props,则需要传递 超级道具。否则没关系,因为React设置了.props 从外部调用实例后 构造函数。
答案 9 :(得分:1)
对于React版本16.6.3,我们使用 super(props)初始化状态元素 name:this.props.name >
constructor(props){
super(props);
}
state = {
name:this.props.name
//otherwise not defined
};