ChatGPT解决这个技术问题 Extra ChatGPT

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

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

class MyComponent extends React.Component {
  constructor(props) {
    super(); // or super(props) ?
  }
}
也可以在 overreacted.io/why-do-we-write-super-props 找到一个很好的解释

R
Robin Pokorny

需要将 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 的使用没有影响。即 rendershouldComponentUpdate 或事件处理程序始终 可以访问它。

这在 Sophie Alpert 的一个类似问题的 answer 中明确表示。

文档—State and Lifecycle, Adding Local State to a Class, point 2—建议:

类组件应始终使用 props 调用基本构造函数。

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

(感谢@MattBrowne 提供链接)


我认为您是正确的,尽管其他答案获得了更多选票。 this.propsundefined,除非传递给 super()。无论哪种方式,它都不会影响 render() 函数中 this.props 的后续呈现或可用性。
@Rotareti,不,实际上课程的其余部分不依赖于这个结构,这就是重点。组件通过与构造函数参数不同的方式接收道具。由于您将初始道具传递给 super,因此您在构造函数中引用了它们。
根据 React 文档,您应该始终将 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.propsin from constructor 的方法,例如 this.doStuffUsingThisDotProps(),而无需将 props 参数传递给这些方法/函数。根据这个问题的答案,我刚刚写了一个构造函数,这似乎需要我首先使用 super(props)
A
Ankur Soni

在此示例中,您正在扩展 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) 之间的区别)。
N
Nahush Farkande

当您将 props 传递给 super 时,道具将分配给 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 时。
D
Daniel

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


S
Silicum Silium

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

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

z
zerkms

根据source code

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

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


这一点我还不是很清楚。如果您查看 these 两个 components,您可以看到一个调用 super(props) 而另一个没有。但他们的消费者都设置了道具。有什么区别?
这是否意味着 this.props = propssuper(props) 是同一个东西?
这不是真的。 ReactElement 实际上是从“外部”设置 this.props——不管在构造函数中做了什么。
k
kspence

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

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

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

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


是的,它就是这样做的。但为什么? React 何时需要两种形式之一?
N
Narendra Jadhav

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

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

V
VIKAS KOHLI

在这里,我们不会在构造函数中获取 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 值

Sophie Alpert's Answer

如果要在构造函数中使用 this.props,则需要将 props 传递给 super。否则,没关系,因为 React 在调用构造函数后立即从外部设置实例上的 .props。


S
Silicum Silium

这是我制作的小提琴:jsfiddle.net。它表明默认情况下,props 不是在构造函数中分配的。据我了解,它们是在方法 React.createElement 中分配的。因此,只有当超类的构造函数手动将 props 分配给 this.props 时,才应调用 super(props)。如果您只是扩展 React.Component,则调用 super(props) 不会对 props 做任何事情。也许它会在下一个版本的 React 中改变。