262 votes

Composant React initialisant l'état à partir de props

Dans React, y a-t-il de réelles différences entre ces deux implémentations ? Certains amis me disent que le FirstComponent est le modèle, mais je ne vois pas pourquoi. Le site SecondComponent semble plus simple car le rendu n'est appelé qu'une seule fois.

D'abord :

import React, { PropTypes } from 'react'

class FirstComponent extends React.Component {

  state = {
    description: ''
  }

  componentDidMount() {
    const { description} = this.props;
    this.setState({ description });
  }

  render () {
    const {state: { description }} = this;    
    return (
      <input type="text" value={description} /> 
    );
  }
}

export default FirstComponent;

Deuxièmement :

import React, { PropTypes } from 'react'

class SecondComponent extends React.Component {

  state = {
    description: ''
  }

  constructor (props) => {
    const { description } = props;
    this.state = {description};
  }

  render () {
    const {state: { description }} = this;    
    return (
      <input type="text" value={description} />   
    );
  }
}

export default SecondComponent;

Mise à jour : J'ai changé setState() a this.state = {} (merci joews), Cependant, je ne vois toujours pas la différence. L'un est-il meilleur que l'autre ?

0 votes

Bonjour, merci pour les liens, ces composants sont juste un échantillon, mais comment vous liez montrer facebook.github.io/react/tips/ Je peux mettre les props dans l'état si j'ai besoin de ces données après ... la question ici est de savoir comment je dois stocker la date des props dans mon état.

12 votes

Un exemple : un composant basculant (par exemple, un popover ou un tiroir). Le parent sait si le composant doit être ouvert ou fermé ; le composant lui-même peut savoir s'il est ouvert ou non à un moment donné. Dans ce cas, je pense que this.state = { isVisible: props.isVisible } a du sens. Cela dépend de la façon dont l'application distribue l'état de l'interface utilisateur.

2 votes

Vous devriez lire ceci medium.com/@justintulk/

231voto

Cabloo Points 150

Il convient de noter que la copie de propriétés qui ne changent jamais dans l'état est un anti-modèle (il suffit d'accéder directement à .props dans ce cas). Si vous avez une variable d'état qui changera éventuellement mais qui commence avec une valeur provenant de .props, vous n'avez même pas besoin d'appeler le constructeur - ces variables locales sont initialisées après un appel au constructeur du parent :

class FirstComponent extends React.Component {
  state = {
    x: this.props.initialX,
    // You can even call functions and class methods:
    y: this.someMethod(this.props.initialY),
  };
}

C'est un équivalent abrégé de la réponse de @joews ci-dessous. Il semble que cela ne fonctionne que sur les versions plus récentes des transpilers es6, j'ai eu des problèmes avec cela sur certaines configurations de webpack. Si cela ne fonctionne pas pour vous, vous pouvez essayer d'ajouter le plugin babel. babel-plugin-transform-class-properties ou vous pouvez utiliser la version non abrégée de @joews ci-dessous.

1 votes

Pouvez-vous expliquer davantage en quoi votre réponse est différente de celle de @joews ?

3 votes

Ajouté "Vous pouvez sauter l'appel au constructeur si tout ce que vous faites est de définir des variables".

3 votes

Si cela ne fonctionne pas, vous devez probablement installer ce plugin babel "babel-plugin-transform-class-properties".

157voto

joews Points 4953

Vous n'avez pas besoin d'appeler setState dans un composant constructor - il est idiomatique de mettre this.state directement :

class FirstComponent extends React.Component {

  constructor(props) {
    super(props);

    this.state = {
      x: props.initialX
    };
  }
  // ...
}

Voir React docs - Ajout d'un état local à une classe .

La première méthode que vous décrivez ne présente aucun avantage. Elle entraînera une deuxième mise à jour immédiatement avant le montage du composant pour la première fois.

8 votes

Bonne réponse. Il peut être utile de noter que cela ne sert qu'à définir l'état initial ; vous devez toujours utiliser la fonction setState si vous le mutez à un autre moment, sinon les modifications risquent de ne pas être rendues.

0 votes

Merci encore jowes, je seconde la documentation facebook.github.io/react/docs/

0 votes

(désolé, j'ai appuyé sur la touche entrée..) nous devrions utiliser getInitialState pour définir les props à l'état, dans des tâches plus complexes, si c'est simple nous pouvons juste utiliser this.props dans le rendu, correct ?

42voto

Ashley Coolman Points 356

Mise à jour pour React 16.3 alpha introduit static getDerivedStateFromProps(nextProps, prevState) ( docs ) en remplacement de componentWillReceiveProps .

getDerivedStateFromProps est invoqué après l'instanciation d'un composant ainsi que lorsqu'il reçoit de nouveaux props. Il doit retourner un objet pour mettre à jour l'état, ou null pour indiquer que les nouveaux props ne nécessitent aucune mise à jour de l'état.

Notez que si un composant parent provoque un nouveau rendu de votre composant, cette méthode sera appelée même si les props n'ont pas changé. Vous pouvez comparer les nouvelles valeurs et les précédentes si vous souhaitez uniquement gérer les modifications.

https://reactjs.org/docs/react-component.html#static-getderivedstatefromprops

Il est statique, il n'a donc pas d'accès direct à l'information. this (cependant, il a accès à prevState qui pourrait stocker des éléments normalement rattachés à this par exemple refs )

édité pour refléter la correction de @nerfologist dans les commentaires

3 votes

Juste pour clarifier, il s'appelle getDerivedStateFromProps (marquez la lettre majuscule dans Props) et les paramètres sont nextProps , prevState (pas nextState ) : reactjs.org/docs/

2 votes

Wow ! nous pouvons utiliser ceci pour mettre à jour l'état quand accessoires mis à jour sont reçus !

2 votes

Doit-on encore créer l'état initial dans le constructeur, en considérant que l'élément getDerivedStateFromProps est toujours appelé avant le rendu initial ?

24voto

dacharjaya Points 141

Vous pouvez utiliser le formulaire court comme ci-dessous si vous souhaitez ajouter tous les accessoires à l'état et conserver les mêmes noms.

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

1 votes

C'est un anti-modèle de copier des propriétés qui ne changent jamais dans l'état. Il est préférable de décrire explicitement les champs que votre composant utilise.

3voto

sujithklr93 Points 97

Si vous initez directement l'état à partir des props, il y aura un avertissement dans React 16.5 (5 septembre 2018).

0 votes

Une idée de la raison de cet avertissement ?

2 votes

On dirait que c'est seulement si vous utilisez state = props . Plus d'informations ici : github.com/facebook/react/pull/11658#issuecomment-419677176

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