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
.
this.state
Et setState
?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:
hasSubmit
setfalse
dansgetInitialState()
.hasSubmit
sera remplacé parfalse
lorsque je clique sur le boutonsubmit
.hasSubmit
sera remplacé partrue
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 .
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 dansshouldComponentUpdate()
.Si des objets modifiables sont utilisés et que la logique ne peut pas être implémentée dans
shouldComponentUpdate()
, l'appel desetState()
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.
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` ...
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
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
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é.
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.