Je travaille sur de Réagir.
TLDR:
Mais pouvez-vous faire confiance à Réagir à la mise à jour de l'état dans le même ordre que setState est appelé pour
Oui.
- les différents composants?
Oui.
L' ordre des mises à jour est toujours respecté. Si vous voyez un état intermédiaire "entre" eux ou pas dépend de si vous êtes à l'intérieur d'un lot ou pas.
Actuellement (réaction de 16 et plus tôt), seules les mises à jour à l'intérieur de Réagir gestionnaires d'événements sont groupées par défaut. Il y a une instabilité de l'API à force de traitement par lots à l'extérieur de gestionnaires d'événements pour les rares cas où vous en avez besoin.
Dans les futures versions (probablement Réagir 17 et plus tard), de Réagir lot toutes les mises à jour par défaut, de sorte que vous n'aurez pas à penser à ce sujet. Comme toujours, nous allons annoncer tout changement à ce sujet sur le Réagir blog et dans les notes de version.
La clé pour comprendre c'est que peu importe combien de setState()
des appels dans la façon dont de nombreux composants dont vous n'avez à l'intérieur d'une Réagir gestionnaire d'événements, ils ne produisent qu'une seule rendre à nouveau à la fin de l'événement. Ceci est crucial pour une bonne performance dans les applications de grande taille, car si Child
et Parent
chaque appel setState()
lors de la manipulation d'un événement de clic, vous ne voulez pas de re-rendre l' Child
deux fois.
Dans les deux exemples, setState()
des appels se produisent à l'intérieur d'une Réagir gestionnaire d'événement. Par conséquent, ils sont toujours vidée à la fin de l'événement (et vous ne voyez pas l'état intermédiaire).
Les mises à jour sont toujours faiblement fusionné dans l'ordre où ils se produisent. Donc, si la première mise à jour est - {a: 10}
, le second est {b: 20}
, et la troisième est {a: 30}
, le rendu de l'état sera {a: 30, b: 20}
. La plus récente mise à jour de l'état de clés (par exemple, a
dans mon exemple) toujours "gagne".
L' this.state
objet est mis à jour lorsque nous nous ré-rendu de l'INTERFACE utilisateur à la fin du lot. Donc, si vous avez besoin de mettre à jour l'état basé sur un état antérieur (tels que l'incrémentation d'un compteur de), vous devez utiliser la fonctionnelle setState(fn)
version qui vous donne l'état précédent, au lieu de lire à partir d' this.state
. Si vous êtes curieux de connaître le raisonnement pour cela, je vous l'ai expliqué en profondeur dans ce commentaire.
Dans votre exemple, de ne pas nous voir "l'état intermédiaire" parce que nous sommes à l'intérieur d'une Réagir gestionnaire d'événements où le dosage est activé (en raison de Réagir "sait" quand nous sommes sortie de cet événement).
Toutefois, les deux à Réagir 16 et versions antérieures, il n'existe pas encore de traitement par lots, par défaut, à l'extérieur de Réagir gestionnaires d'événements. Alors, si dans votre exemple, nous avons eu une réponse AJAX gestionnaire au lieu de handleClick
chaque setState()
seraient traités immédiatement, comme il arrive. Dans ce cas, oui, vous permettrait de voir un état intermédiaire:
promise.then(() => {
// We're not in an event handler, so these are flushed separately.
this.setState({a: true}); // Re-renders with {a: true, b: false }
this.setState({b: true}); // Re-renders with {a: true, b: true }
this.props.setParentState(); // Re-renders the parent
});
Nous nous rendons compte qu'il est gênant que le comportement est différent selon que vous êtes dans un gestionnaire d'événement ou pas. Cela va changer dans un avenir Réagir version qui sera le lot de toutes les mises à jour par défaut (et de fournir un opt-in API pour vider les changements de manière synchrone). Jusqu'à ce que nous changer le comportement par défaut (peut-être Réagir 17), il existe une API que vous pouvez utiliser pour forcer le traitement par lots:
promise.then(() => {
// Forces batching
ReactDOM.unstable_batchedUpdates(() => {
this.setState({a: true}); // Doesn't re-render yet
this.setState({b: true}); // Doesn't re-render yet
this.props.setParentState(); // Doesn't re-render yet
});
// When we exit unstable_batchedUpdates, re-renders once
});
En interne Réagir les gestionnaires d'événements sont en train d'être enveloppé dans unstable_batchedUpdates
qui est pourquoi elles sont groupées par défaut. Notez que l'enchaînement d'un jour, en unstable_batchedUpdates
deux fois n'a pas d'effet. Les mises à jour sont vidés quand nous sortons de la ultrapériphériques unstable_batchedUpdates
appel.
Cette API est "instable" dans le sens que nous allons en retirer quand le dosage est déjà activé par défaut. Cependant, nous n'avons pas le supprimer dans une version mineure, vous pouvez compter sur elle jusqu'à ce que Réagir 17 si vous avez besoin de la force de dosage, dans certains cas, à l'extérieur de Réagir gestionnaires d'événements.
Pour résumer, c'est un sujet à confusion en raison de Réagir qu'à des lots à l'intérieur des gestionnaires d'événement par défaut. Cela va changer dans les futures versions, et le comportement sera plus simple ensuite. Mais la solution n'est pas de lot moins, c'est le lot de plus par défaut. C'est ce que nous allons faire.