Was ist der Unterschied zwischen "super ()" und "super (Requisiten)" in React, wenn es6-Klassen verwendet werden?

532

Wann ist es wichtig , passieren propszu super(), und warum?

class MyComponent extends React.Component {
  constructor(props) {
    super(); // or super(props) ?
  }
}
Mischa Moroshko
quelle
7
Eine gute Erklärung finden Sie auch unter überreagiert.io
why-do-we-write-super-props

Antworten:

710

Es gibt nur einen Grund , wenn man passieren muss , propsum super():

Wenn Sie this.propsim Konstruktor zugreifen möchten .

Vorbeigehen:

class MyComponent extends React.Component {    
    constructor(props) {
        super(props)

        console.log(this.props)
        // -> { icon: 'home', … }
    }
}

Nicht vorbei:

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

Beachten Sie, dass vorbei oder nicht vorbei propsan superhat keinen Einfluss auf die spätere Verwendungen von this.propsaußen constructor. Das heißt render, shouldComponentUpdateoder Ereignishandler haben immer Zugriff darauf.

Dies wird ausdrücklich in einer Antwort von Sophie Alpert auf eine ähnliche Frage gesagt .


In der Dokumentation - Status und Lebenszyklus, Hinzufügen eines lokalen Status zu einer Klasse, Punkt 2 - wird empfohlen:

Klassenkomponenten sollten immer den Basiskonstruktor mit aufrufen props.

Es wird jedoch kein Grund angegeben. Wir können spekulieren, dass dies entweder auf Unterklassen oder auf zukünftige Kompatibilität zurückzuführen ist.

(Danke @MattBrowne für den Link)

Robin Pokorny
quelle
16
Ich denke, Sie haben Recht, obwohl die anderen Antworten mehr Stimmen erhalten. this.propsist undefinedes sei denn, an übergeben super(). In beiden Fällen hat dies keinen Einfluss auf das spätere Rendern oder die Verfügbarkeit this.propsder render()Funktion.
Micros
3
@ Rotareti, nein, eigentlich hängt der Rest der Klasse nicht von diesem Konstrukt ab, das ist der Punkt. Die Komponente empfängt Requisiten auf eine andere Weise als durch den Konstruktorparameter. Und da Sie die ersten Requisiten an übergeben super, haben Sie im Konstruktor einen Verweis darauf.
Robin Pokorny
7
Gemäß der React-Dokumentation sollten Sie immer propsan super()folgende Adresse übergeben : facebook.github.io/react/docs/… . Ich bin mir nicht sicher, warum, da, wie Sie hervorheben, this.propsauf andere Weise auf beide Methoden zugegriffen werden kann. Vielleicht empfehlen sie dies aus Gründen der zukünftigen Kompatibilität, falls zukünftige Versionen von React möglicherweise etwas propsim Konstruktor tun möchten .
Matt Browne
23
Vielleicht öffne ich hier nur eine Dose Würmer, aber warum solltepropssuperprops ich jemals darauf übergehen , wenn, wie Sie betont haben, der Parameter genau dort verfügbar ist, damit wir ihn im Konstruktor verwenden können , und this.propsüberall anders funktioniert? Gibt es überhaupt einen Vorteil, wenn man this.propsmehr als nur verwendet props? Ist es eine schlechte Praxis, propsim Konstruktor abzubrechen? Ich glaube , ich bin immer noch nicht um einen Fall zu sehen , wenn Sie jemals passieren bräuchten propszu super, aber ich bin bereit , es ist nur meine Unwissenheit zu wetten, ha.
Indiesquidge
9
Wenn Sie verwenden super(props), können Sie Methoden aufrufen, die this.props vom Konstruktor aus verwendet werden this.doStuffUsingThisDotProps(), ohne den Parameter props an diese Methoden / Funktionen übergeben zu müssen. Ich habe gerade einen Konstruktor geschrieben, der dies tut, was anscheinend erfordern würde, dass ich super(props)zuerst gemäß den Antworten auf diese Frage benutze .
Victor Zamanian
54

In diesem Beispiel erweitern Sie die React.ComponentKlasse, und gemäß der ES2015-Spezifikation kann ein untergeordneter Klassenkonstruktor erst dann verwendet werden, thiswenn super()er aufgerufen wurde. Außerdem müssen ES2015-Klassenkonstruktoren aufrufen, super()wenn sie Unterklassen sind.

class MyComponent extends React.Component {
  constructor() {
    console.log(this); // Reference Error
  }

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

Im Gegensatz:

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

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

Weitere Details finden Sie in dieser hervorragenden Antwort zum Stapelüberlauf

Möglicherweise sehen Sie Beispiele für Komponenten, die durch Erweitern der React.ComponentKlasse erstellt wurden und nicht aufgerufen werden. super()Sie werden jedoch feststellen, dass diese keine haben constructor, weshalb dies nicht erforderlich ist.

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

Ein Punkt der Verwirrung, den ich von einigen Entwicklern gesehen habe, mit denen ich gesprochen habe, ist, dass die Komponenten, die keine haben constructorund daher super()nirgendwo aufrufen , immer noch this.propsin der render()Methode verfügbar sind . Denken Sie daran, dass diese Regel und die Notwendigkeit, eine thisBindung für die zu erstellen, constructornur für die gilt constructor.

Dave
quelle
15
Vielen Dank für Ihre Antwort, aber sie beantwortet meine ursprüngliche Frage nicht (Unterschied zwischen super()und super(props)).
Mischa Moroshko
46

Wenn Sie propsan übergeben super, werden die Requisiten zugewiesen this. Schauen Sie sich das folgende Szenario an:

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

Wie auch immer, wenn Sie:

constructor(props) {
    super(props);
    console.log(this.props) //props will get logged.
}
Nahush Farkande
quelle
Die beste Antwort in der Liste.
Basavaraj Hadimani
Diese Antwort ist halb richtig. Dieses Beispiel gilt nur für die Konstruktormethode. Selbst wenn Sie beispielsweise keine Super-Requisiten schreiben, wird this.props unter der Render-Methode weiterhin zugewiesen und ist verfügbar. Der einzige oben erwähnte Grund ist die Verwendung von this.props im Konstruktor.
Ofear
12

Wie pro Quellcode

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

Sie müssen propsjedes Mal bestehen, wenn Sie Requisiten haben, und Sie setzen sie nicht this.propsmanuell ein.

zerkms
quelle
1
Mir ist das immer noch nicht klar. Wenn Sie sich diese beiden Komponenten ansehen , sehen Sie einen Anruf super(props)und den anderen nicht. Aber ihre Verbraucher setzen beide Requisiten. Was ist der Unterschied?
Kyeotic
Bedeutet das das this.props = propsund super(props)ist dasselbe?
Reectrix
1
Das ist nicht wahr. ReactElement wird tatsächlich this.propsvon außen festgelegt - unabhängig davon, was im Konstruktor ausgeführt wird.
Robin Pokorny
11

Dan Abramov hat einen Artikel zu diesem Thema geschrieben:

Warum schreiben wir super (Requisiten)?

Und das Wesentliche dabei ist, dass es hilfreich ist, die Gewohnheit zu haben , es zu bestehen, um dieses Szenario zu vermeiden. Ehrlich gesagt sehe ich es nicht als unwahrscheinlich an:

// 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 
  }
  // ...
}
Alfonso Pérez
quelle
8

super() wird verwendet, um den übergeordneten Konstruktor aufzurufen.

super(props)würde propsan den übergeordneten Konstruktor übergeben.

In Ihrem Beispiel super(props)würde der übergebende React.ComponentKonstruktor propsals Argument aufgerufen .

Weitere Informationen unter super: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/super

kspence
quelle
18
Ja, das ist es, was es tut. Aber warum ? Und wann ist eine der beiden Formen in React erforderlich?
Bergi
7

Bei der Implementierung der constructor()Funktion in einer React-Komponente super()ist dies erforderlich. Beachten Sie, dass Ihre MyComponentKomponente Funktionen aus der React.ComponentBasisklasse erweitert oder ausleiht .

Diese Basisklasse hat eine eigene constructor()Funktion, die Code enthält, um unsere React-Komponente für uns einzurichten.

Wenn wir eine constructor()Funktion innerhalb unserer MyComponentKlasse definieren , überschreiben oder ersetzen wir im Wesentlichen die constructor()Funktion innerhalb der React.ComponentKlasse, müssen jedoch sicherstellen, dass der gesamte Setup-Code innerhalb dieser constructor()Funktion weiterhin aufgerufen wird.

So , um sicherzustellen , dass die React.Components‘ constructor()Funktion aufgerufen wird, rufen wir super(props). super(props)ist ein Hinweis auf die Elternfunktion constructor(), das ist alles was es ist.

Wir müssen super(props)jedes Mal hinzufügen, wenn wir eine constructor()Funktion innerhalb einer klassenbasierten Komponente definieren.

Wenn wir dies nicht tun, wird ein Fehler angezeigt, der besagt, dass wir anrufen müssen super(props).

Der gesamte Grund für die Definition dieser constructor()Funktion besteht darin, unser Statusobjekt zu initialisieren.

Um unser Statusobjekt zu initialisieren, schreibe ich unter den Superaufruf:

class App extends React.Component {
  constructor(props) {
      super(props);

      this.state = {};
   }

  // React says we have to define render()
  render() {
    return <div>Hello world</div>;
  }
};

Also haben wir unsere constructor()Methode definiert, unser Statusobjekt initialisiert, indem wir ein JavaScript-Objekt erstellt, ihm eine Eigenschaft oder ein Schlüssel / Wert-Paar zugewiesen und das Ergebnis davon zugewiesen haben this.state. Dies ist hier natürlich nur ein Beispiel, daher habe ich dem Statusobjekt nicht wirklich ein Schlüssel / Wert-Paar zugewiesen, es ist nur ein leeres Objekt.

Daniel
quelle
4

Hier ist die Geige, die ich gemacht habe: jsfiddle.net . Es zeigt, dass Requisiten standardmäßig nicht im Konstruktor zugewiesen sind. Soweit ich weiß, werden sie in der Methode bewertet React.createElement. Daher super(props)sollte nur dann , wenn die übergeordnete Klasse Konstruktor manuell assings aufgerufen werden propszu this.props. Wenn Sie nur den React.ComponentAnruf verlängern , super(props)wird nichts mit Requisiten tun. Vielleicht wird es in den nächsten Versionen von React geändert.

beshanoe
quelle
3

Hier erhalten wir dies nicht im Konstruktor, so dass es undefiniert zurückgibt, aber wir können dies außerhalb der Konstruktorfunktion abrufen

class MyComponent extends React.Component {
  constructor() {
    console.log(this); // Reference Error i.e return undefined
  }

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

Wenn wir super () verwenden, können wir die Variable "this" auch im Konstruktor abrufen

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

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

Also, wenn wir super () verwenden; Wir werden dies abrufen können, aber this.props sind im Konstruktor undefiniert. Anders als der Konstruktor gibt this.props jedoch nicht undefiniert zurück.

Wenn wir super (Requisiten) verwenden, können wir diesen.props-Wert auch im Konstruktor verwenden

Sophie Alperts Antwort

Wenn Sie this.props im Konstruktor verwenden möchten, müssen Sie Requisiten an super übergeben. Andernfalls spielt es keine Rolle, da React unmittelbar nach dem Aufruf des Konstruktors .props von außen auf die Instanz setzt.

VIKAS KOHLI
quelle
3

Für die Reaktionsversion 16.6.3 verwenden wir super (Requisiten) , um den Namen des Statuselements zu initialisieren : this.props.name

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