web-dev-qa-db-fra.com

Puis-je utiliser la fonction flèche dans le constructeur d'un composant React?

Cette question est similaire à Lors de l'utilisation de React Est-il préférable d'utiliser des fonctions de flèche épaisse ou de lier des fonctions dans le constructeur? mais un peu différent. Vous pouvez lier une fonction à this dans le constructeur, ou appliquez simplement la fonction flèche dans le constructeur. Notez que je ne peux utiliser que la syntaxe ES6 dans mon projet.

1.

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

    this.doSomeThing = this.doSomeThing.bind(this);
  }

  doSomething() {}
}

2.

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

    this.doSomeThing = () => {};
  }
}

Quels sont les avantages et les inconvénients de ces deux façons? Merci.

17
ycavatars

L'option 1 est généralement plus préférable pour certaines raisons.

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

    this.doSomeThing = this.doSomeThing.bind(this);
  }

  doSomething() {}
}

La méthode du prototype est plus propre à étendre. La classe enfant peut remplacer ou étendre doSomething avec

doSomething() {
  super.doSomething();
  ...
}

Lorsque la propriété d'instance

this.doSomeThing = () => {};

ou champ de classe ES.next

doSomeThing = () => {}

sont utilisés à la place, appeler super.doSomething() n'est pas possible, car la méthode n'était pas définie sur le prototype. Le remplacer entraînera l'affectation de la propriété this.doSomeThing Deux fois, dans les constructeurs parent et enfant.

Des méthodes prototypes sont également accessibles pour les techniques de mixage:

class Foo extends Bar {...}
Foo.prototype.doSomething = Test.prototype.doSomething;

Les méthodes prototypes sont plus testables. Ils peuvent être espionnés, tronqués ou moqués avant l'instanciation de la classe:

spyOn(Foo.prototype, 'doSomething').and.callThrough();

Cela permet d'éviter les conditions de course dans certains cas.

10
Estus Flask

Je pense que vous voudrez peut-être comme ça. C'est la même chose avec votre première situation. cela fonctionnera au stade 2 avec babel. (propriétés de classe de transformation: http://babeljs.io/docs/plugins/transform-class-properties/ ) (preset-stage-2: http: // babeljs. io/docs/plugins/preset-stage-2 / )

class Test extends React.Component{
  constructor(props) {
    super(props);
  }
  doSomeThing = () => {}
}
3
Wei

L'approche 1 est plus lisible pour moi et plus idiomatique.

En outre, en déclarant des méthodes à l'intérieur d'une classe au lieu d'un constructeur, les méthodes peuvent être partagées.

class Foo {
  test() {}
}

const f1 = new Foo()
const f2 = new Foo()
f1.test === f2.test // true

Dans l'approche 2, vous déclarerez toutes les méthodes à chaque fois que vous créez une nouvelle instance:

class Foo {
  constructor() {
    this.test = () => {}
  }
}

const f1 = new Foo()
const f2 = new Foo()
// the method is not shareable
f1.test === f2.test // false

Théoriquement, l'approche 2 est plus lente, mais l'impact sur les performances devrait être négligeable.

Je vais simplement opter pour l'approche 1, car elle est utilisée dans la documentation React , je n'ai jamais vu personne utiliser l'approche 2.


Je viens de lancer quelques échantillons pour tester les performances. Dans le dernier Chrome (Mac), la déclaration des méthodes dans le constructeur est environ 90% plus lente que l'utilisation de bind dans le constructeur.

3
CodinCat

Regarde ça:

https://babeljs.io/repl/#?babili=false&evaluate=true&lineWrap=false&presets=es2015%2Creact%2Cstage-2&targets=&browsers=&builtIns=false&debug=false&code=class%20Dog%20%7 20% 20 constructeur ()% 20% 7B% 0A% 20% 20% 20% 20% 0A% 20% 20% 20% 20this.cat% 20% 3D% 20_% 3D% 3E% 20% 7B% 0A% 20% 20% 20% 20% 20% 20e est% 0A% 20% 20% 20% 20% 7D% 0A% 20% 20% 7D% 0A% 7D

Nous pouvons voir des transbordements de babel

this.doSomeThing = () => { this };

dans

var _this = this;
this.doSomething = function() { _this }

edit: J'ai mal lu votre message, mais ce qui précède est toujours vrai et intéressant. @CodinCat souligne la chose importante: déclarer une fonction à l'intérieur du constructeur signifie qu'il faut du temps (bien que très peu) pour ajouter cette fonction à l'objet lors de sa création, et prend probablement aussi de la mémoire car les instances de cette classe ne partagent pas le même méthode doSomeThing.

edit2: la liaison (ceci) à la fonction provoque en fait les problèmes exacts que j'ai énumérés ci-dessus. En d'autres termes, les deux méthodes sont presque exactement les mêmes.

1
Elliot E