58 votes

Est-il préférable de définir l'état dans le constructeur ou à l'aide de la propriété des initialiseurs?

Selon cette babel de la documentation, de la façon correcte d'utiliser ES6+ à Réagir est de composants initiaux comme ceci:

class Video extends React.Component {
  static defaultProps = {
    autoPlay: false,
    maxLoops: 10,
  }
  static propTypes = {
    autoPlay: React.PropTypes.bool.isRequired,
    maxLoops: React.PropTypes.number.isRequired,
    posterFrameSrc: React.PropTypes.string.isRequired,
    videoSrc: React.PropTypes.string.isRequired,
  }
  state = {
    loopsRemaining: this.props.maxLoops,
  }
}

Mais certains exemples, comme Dan Abramov propre Réagir Mdn module utilise ES6+ mais encore définit l'état dans le constructeur:

constructor(props) {
    super(props);
    this.moveCard = this.moveCard.bind(this);
    this.state = {
       // state stuff
    }
}

Maintenant, Dan Abramov, d'être un contributeur important à Réagir, ne sait probablement qu'il peut définir un état hors de l'constructeur, mais encore choisit de le faire dans le constructeur.

Donc, je me demande juste où est le mieux et pourquoi?

74voto

8voto

estus Points 5252

Ils sont équivalents, car le champ classe de proposition est sucre syntaxique pour le corps du constructeur de code.

Dans le cas où il n'y a pas besoin explicite du constructeur (création de locaux temporaires de variables, etc), constructor peut être omis en faveur des champs de la classe.

Le problème avec explicite constructeur est qu' super arguments (props) sont souvent omis par erreur, cela peut entraîner des problèmes:

constructor() {
    super();
    this.state = { foo: this.props.foo } // this.props is undefined
}

Explicite constructeur peut bénéfiques pour des raisons de lisibilité. Les méthodes conventionnelles placé au-dessous de constructor, même flèche propriétés. Cela ne fonctionne pas comme prévu en raison des champs de classe sont attribués dans l'ordre qu'ils ont été répertoriés:

state = { foo: { method: this.someMethod } } // this.someMethod is undefined

someMethod = () => ...;

Dans ce cas explicite constructeur peut produire un code plus lisible:

constructor(props) {
    super(props);

    // <-- this is the place where this.someMethod is really assigned

    this.state = { foo: { method: this.someMethod } }
}

someMethod = () => ...;

1voto

Gunchars Points 699

Dan code a effectivement un bug subtil et c'est pourquoi je recommande d'utiliser les initialiseurs chaque fois que possible. Réagir composant les constructeurs prennent deux arguments - les accessoires et le contexte. Il n'est pas de le transmettre au constructeur parent et il pourrait facilement être manqué par un autre développeur qui en ont besoin.

Parfois, vous n'avez pas le choix, comme lorsque l'initialiseur repose sur les arguments du constructeur, donc n'oubliez pas de passer tous les arguments pour le parent.

Après avoir essayé quelques choses, ressemble à Réagir n'est pas la question je pensais. Vous pouvez entrer ce que vous voulez le constructeur parent et ce sera très bien. E. g.:

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

  render() {
    // this.props will still be set correctly here
  }
}

Je continue de recommander à l'aide de la initialiseurs de ne pas avoir à appeler le constructeur parent est une chose de moins à penser.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X