web-dev-qa-db-fra.com

Quelle est la différence entre "super ()" et "super (accessoires)" dans React lors de l'utilisation de classes es6?

Quand est-il important de passer props à super() et pourquoi?

class MyComponent extends React.Component {
  constructor(props) {
    super(); // or super(props) ?
  }
}
398
Misha Moroshko

Il y a une seule raison pour laquelle il faut passer props à super():

Lorsque vous souhaitez accéder à this.props dans le constructeur.

Qui passe:

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

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

Ne passant pas:

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

Notez que le fait de passer ou non de props à super n'a que aucun effet sur les utilisations ultérieures de this.props extérieur de constructor. C'est render, shouldComponentUpdate ou les gestionnaires d'événements always y ont accès.

Ceci est explicitement dit dans un réponse de Sophie Alpert à une question similaire.


La documentation — État et cycle de vie, Ajout de l'état local à une classe, point 2 — recommande:

Les composants de classe doivent toujours appeler le constructeur de base avec props.

Cependant, aucune raison n'est fournie. Nous pouvons supposer que cela est dû soit à un sous-classement, soit à une compatibilité future.

(Merci @MattBrowne pour le lien)

568
Robin Pokorny

Dans cet exemple, vous étendez la classe React.Component et, conformément à la spécification ES2015, un constructeur de classe enfant ne peut pas utiliser this tant que l'appel de super() n'a pas eu lieu; De plus, les constructeurs de classe ES2015 doivent appeler super() s'ils sont des sous-classes.

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

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

Par contre:

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

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

Plus de détails selon cette excellente réponse de débordement de pile

Vous pouvez voir des exemples de composants créés en étendant la classe React.Component qui n’appellent pas super() mais vous remarquerez qu’ils n’ont pas de constructor, ce qui explique pourquoi ce n’est pas nécessaire.

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

Un point de confusion que j'ai vu chez certains développeurs avec lesquels j'ai parlé est que les composants qui n'ont pas de constructor et donc n'appellent pas super() nulle part, ont toujours this.props disponible dans la méthode render(). Rappelez-vous que cette règle et cette nécessité de créer une liaison this pour la constructor s'applique uniquement à la constructor.

47
Dave

Lorsque vous passez de props à super, les accessoires sont affectés à this. Examinez le scénario suivant:

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

Comment quand tu fais:

constructor(props) {
    super(props);
    console.log(this.props) //props will get logged.
}
37
Nahush Farkande

Selon code source

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

vous devez passer props chaque fois que vous avez des accessoires et vous ne les mettez pas dans this.props manuellement.

11
zerkms

super() est utilisé pour appeler le constructeur parent. 

super(props) transmettrait props au constructeur parent. 

A partir de votre exemple, super(props) appellerait le constructeur React.Component en passant props en argument.

Plus d'informations sur super: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/super

5
kspence

Voici le violon que j'ai fait: https://jsfiddle.net/beshanoe/zpxbLw4j/1/ . Cela montre que les accessoires ne sont pas affectés par défaut au constructeur. Si je comprends bien, ils sont évalués dans la méthode React.createElement. Par conséquent, super(props) ne devrait être appelé que lorsque le constructeur de la superclasse associe manuellement props à this.props. Si vous prolongez le React.Component, appeler super(props) ne fera rien avec les accessoires. Peut-être que cela sera changé dans les prochaines versions de React.

4
beshanoe

Dan Abramov a écrit un article sur ce sujet:

https://overreacted.io/why-do-we-write-super-props/

Et l’essentiel est qu’il est utile d’avoir l’habitude de le passer pour éviter ce scénario, honnêtement, je ne vois pas cela qui risque de se produire:

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

Lors de l'implémentation de la fonction constructor() dans un composant React, super() est obligatoire. N'oubliez pas que votre composant MyComponent est en train d'étendre ou d'emprunter des fonctionnalités de la classe de base React.Component.

Cette classe de base possède sa propre fonction constructor(), qui contient du code, pour configurer notre composant React pour nous.

Lorsque nous définissons une fonction constructor() dans notre classe MyComponent, nous substituons ou remplaçons la fonction constructor() qui se trouve dans la classe React.Component, mais nous devons néanmoins nous assurer que tout le code de configuration à l'intérieur de cette fonction constructor() est toujours appelé.

Pour que la fonction constructor() de React.Component ’s soit appelée, nous appelons super(props). super(props) est une référence à la fonction constructor() des parents, c’est tout.

Nous devons ajouter super(props) chaque fois que nous définissons une fonction constructor() dans un composant basé sur une classe.

Si nous ne le faisons pas, nous verrons une erreur disant que nous devons appeler super(props).

La raison entière pour définir cette fonction constructor() est d’initialiser notre objet d’état.

Donc, pour initialiser notre objet d'état, sous le super appel, je vais écrire:

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

      this.state = {};
   }

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

Nous avons donc défini notre méthode constructor(), initialisé notre objet state en créant un objet JavaScript, en lui affectant une propriété ou une paire clé/valeur, en attribuant le résultat à this.state. Bien sûr, ceci n’est qu’un exemple ici. Je n’ai donc pas vraiment affecté de paire clé/valeur à l’objet state, c’est un objet vide.

3
Daniel

Ici, nous n'obtiendrons pas ceci dans le constructeur, il retournera donc undefined, mais nous pourrons extraire cela en dehors de la fonction constructeur

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

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

Si nous utilisons super (), nous pouvons aussi récupérer la variable "this" dans le constructeur

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

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

Donc quand on utilise super (); nous pourrons aller chercher ça mais this.props sera indéfini dans le constructeur. Mais à part constructeur, this.props ne retournera pas indéfini.

Si nous utilisons super (props), nous pouvons aussi utiliser la valeur this.props dans le constructeur

Réponse de Sophie Alpert

Si vous voulez utiliser this.props dans le constructeur, vous devez passer les accessoires à super. Sinon, cela n’a aucune importance, car React définit .props sur l'instance de l'extérieur immédiatement après avoir appelé le constructeur.

1
VIKAS KOHLI

Pour réagir à la version 16.6.3, nous utilisons super (props) pour initialiser l’élément d’étatname: this.props.name

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