web-dev-qa-db-fra.com

Quelle est la différence entre this.state et this.setstate dans ReactJS?

Je souhaite modifier la valeur de la clé hasSubmit, comme dans la section Premier code. Je sais que ce n'est pas recommandé. Mais le second code est asynchrone et je ne souhaite pas utiliser la fonction de rappel de setState.

  • Quelle est la différence entre this.state Et setState?
  • Est-il possible de changer la valeur d'état hasSubmit immédiatement?

Premier code:

this.state.hasSubmit = false
this.setState({})
//Code that will use `hasSubmit`.

Deuxième code:

this.setState({
   hasSubmit: false,
});
//Code that will use `hasSubmit`.

AJOUTER:

Le scénario est que:

  1. hasSubmit set false dans getInitialState().
  2. hasSubmit sera remplacé par false lorsque je clique sur le bouton submit.
  3. hasSubmit sera remplacé par true lors de sa soumission.

Le premier clic submit n'a pas de problème et hasSubmit sera défini sur true.

Mais le second clic submit sera faux en utilisant le Second asynchronous code, Car le hasSubmit est toujours true, alors que le First Code Peut résoudre le problème .

46
DanielJyc

Voici ce que disent les docs React :

NE JAMAIS muter this.state Directement, car appeler ensuite setState () peut remplacer la mutation que vous avez effectuée. Traitez cet Etat comme s'il était immuable.

setState() ne mute pas immédiatement this.state mais crée une transition d'état en attente. Accéder à this.state Après avoir appelé cette méthode peut potentiellement renvoyer la valeur existante.

Il n'y a aucune garantie de fonctionnement synchrone des appels à setState et les appels peuvent être mis en lot pour des gains de performances. setState() déclenchera toujours un rendu à moins que la logique de rendu conditionnel soit implémentée dans shouldComponentUpdate().

Si des objets modifiables sont utilisés et que la logique ne peut pas être implémentée dans shouldComponentUpdate(), l'appel de setState() uniquement lorsque le nouvel état diffère de l'état précédent évitera des rediffusions inutiles.

Il est toujours judicieux d'utiliser les API dans leur conception. Si les docs disent de ne pas muter votre état, alors vous feriez mieux de ne pas muter votre état.

Bien que setState() puisse être techniquement asynchrone, il ne ralentit certainement pas de manière notable. La fonction render() du composant sera appelée dans un délai assez court.

Un des inconvénients de la définition directe de l'état est que les méthodes de cycle de vie de React - shouldComponentUpdate(), componentWillUpdate(), componentDidUpdate() - dépendent du fait que les transitions d'état sont appelées avec setState() . Si vous modifiez directement l'état et appelez setState() avec un objet vide, vous ne pourrez plus implémenter ces méthodes.

Une autre est que c'est juste un mauvais style de programmation. Vous faites en deux déclarations ce que vous pourriez faire en un.

De plus, il n'y a aucun avantage réel ici. Dans les deux cas, render() ne sera déclenché qu'après l'appel de setState() (ou forceUpdate()).

Vous prétendez avoir besoin de le faire sans expliquer réellement ce besoin. Peut-être aimeriez-vous détailler un peu plus votre problème? Il y a probablement une meilleure solution.

Il est préférable de travailler avec le cadre plutôt que contre.

MISE À JOUR

Parmi les commentaires ci-dessous:

Le besoin est que je veuille utiliser le hasSubmit modifié ci-dessous.

OK je comprends maintenant. Si vous devez utiliser immédiatement la propriété future state, la meilleure solution consiste simplement à la stocker dans une variable locale.

const hasSubmit = false;

this.setState({
  hasSubmit: hasSubmit
});

if (hasSubmit) { 
  // Code that will use `hasSubmit` ...
50
David L. Walsh

Si vous voulez changer d'état et déclencher un re-rendu par react: Utilisez le deuxième code.

  this.setState({
    hasSubmit: false,
  });

Problèmes/erreurs avec le premier code:

  this.state.hasSubmit = false      // Updates state directly: 
                                    // You are not supposed to do this
                                    // except in ES6 constructors
  this.setState({})                 // passes an empty state to react.
                                    // Triggers re-render without mutating state
5
wintvelt

this.setState maintient le cycle de vie du composant de réaction et ne semble pas être une variable en mutation (même si, en interne, il est en état de mutation). Ainsi, le flux à sens unique dans le cycle de réaction est maintenu sans aucun effet secondaire.

La mise en garde concerne l'utilisation de this.setState ne fonctionne pas avec les constructeurs des classes ES6. Nous devons utiliser this.state = motif plutôt que this.setState dans les constructeurs ES6

4
Aditya Singh

Vous ne devez jamais ignorer les conseils relatifs à la documentation. Au moment de la rédaction, setState autorise un second argument qui est une fonction de rappel lorsque setState et le rendu sont terminés. Étant donné que vous ne nous indiquez jamais comment votre code va utiliser la valeur hasSubmit, je pense qu'un autre peut trouver cela utile lorsqu'il veut s'assurer que hasSubmit a bien été modifié.

3
Sany Liew

Vous devez utiliser this.forceUpdate() dans le premier exemple pour forcer la mise à jour de l'état. Par exemple:

this.state.hasSubmit = false;
this.forceUpdate();

Mais il vaut mieux utiliser this.setState _ parce qu’il s’agit d’un moteur d’initialisation natif de l’état de contrôle React du moteur, ce qui est préférable à la mise à jour forcée).

Si vous venez de mettre à jour un paramètre de this.state directement _ sans setState réagir rendre mecanizm ne saura pas que certains paramètres d'état sont mis à jour.

1
Dmitriy