什么时候传递props
给很重要super()
,为什么?
class MyComponent extends React.Component {
constructor(props) {
super(); // or super(props) ?
}
}
什么时候传递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
有没有影响对以后的用途this.props
之外constructor
。也就是说render
,shouldComponentUpdate
、 或 事件处理程序始终可以访问它。
这在 Sophie Alpert对类似问题的回答中明确表示。
文档——状态和生命周期,将本地状态添加到类,第 2 点——推荐:
类组件应始终使用
props
.
但是,没有提供任何理由。我们可以推测它要么是因为子类化,要么是为了未来的兼容性。
(感谢@MattBrowne 提供链接)
在此示例中,您正在扩展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.props
在render()
方法中仍然可用。请记住,此规则和此需要创建的this
绑定constructor
仅适用于constructor
.
当您传递props
给 时super
,props将被分配给this
。看看下面的场景:
constructor(props) {
super();
console.log(this.props) //undefined
}
你怎么做:
constructor(props) {
super(props);
console.log(this.props) //props will get logged.
}
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
}
// ...
}
在constructor()
React 组件中实现该功能时,这super()
是一项要求。请记住,您的MyComponent
组件正在从React.Component
基类扩展或借用功能。
这个基类有一个constructor()
自己的函数,里面有一些代码,为我们设置我们的 React 组件。
当我们constructor()
在我们的MyComponent
类中定义一个函数时,我们本质上是覆盖或替换了类中的constructor()
函数React.Component
,但我们仍然需要确保这个constructor()
函数中的所有设置代码仍然被调用。
所以为了确保React.Component
的constructor()
函数被调用,我们调用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
。现在当然这只是一个例子,所以我并没有真正为状态对象分配一个键/值对,它只是一个空对象。