web-dev-qa-db-fra.com

Quelles sont les différences lors du nouveau rendu après que l'état a été défini avec Hooks par rapport à l'approche basée sur les classes?

Composants de classe

Dans React composants de classe, on nous dit que setState toujours provoque un nouveau rendu, indépendamment de la modification ou non de l'état par une nouvelle valeur. En effet, un composant sera rendu à nouveau, lorsque l'état sera mis à jour vers même valeur qu'elle était auparavant.

Documents (référence de l'API setState) :

setState () conduira toujours à un nouveau rendu à moins que shouldComponentUpdate () ne retourne false.


Crochets (composants de fonction)

Avec les hooks cependant, les documents spécifient que la mise à jour de l'état à une valeur identique à l'état précédent, ne provoquera pas un nouveau rendu (des composants enfants):

Documents (référence de l'API useState) :

Renonciation à une mise à jour d'état

Si vous mettez à jour un State Hook à la même valeur que l'état actuel, React renflouera sans rendre les enfants ou les effets de tir. (React utilise l'algorithme de comparaison Object.is.)


Questions étroitement liées

  1. Est-il exact que this.setState dans les composants de classe provoquent toujours un nouveau rendu, même lorsque la nouvelle valeur state est identique à la précédente?
  2. Est-il exact que dans composants de fonction avec des crochets, setState de useState ne provoque un nouveau rendu que si la valeur state est différente de la valeur précédente?
  3. Définit state avec this.setState à l'intérieur de la méthode render d'un composant classe, identique à la configuration state à l'intérieur du corps de la fonction d'un composant fonction avec crochets?
  4. Les éléments suivants sont-ils corrects?
    • Dans un composant class, si nous définissons state dans la méthode render, une boucle infinie se produira. C'est parce que le composant class ne se soucie pas que le nouveau state soit le même que le précédent state. Il ne fait que restituer chaque this.setState.
    • Dans un composant de fonction avec des crochets cependant, en définissant state à l'intérieur du corps de la fonction (qui s'exécute à nouveau comme pour la méthode render dans les composants de classe) ne serait pas un problème, car le composant de fonction ne fait que sortir de re -rends quand il voit que le state est identique au précédent state.
20
Magnus

Est-il correct que this.setState dans les composants de classe provoque toujours un nouveau rendu, même lorsque la nouvelle valeur d'état est identique à la précédente?

Si vous définissez une valeur valide en dehors de renvoyer null dans setState, un nouveau rendu sera toujours déclenché par react dans un composant de classe, sauf si votre composant est un PureComponent ou que vous implémentez shouldComponentUpdate

Est-il exact que dans les composants de fonction avec des hooks, setState de useState ne provoque un nouveau rendu que si la valeur d'état est différente de la valeur précédente?

Pour un composant fonctionnel utilisant useState hook, le setter s'il est appelé avec le même état ne déclenchera pas de nouveau rendu. Cependant, pour un cas occasionnel, si le setter est appelé immédiatement, il en résulte deux rendus au lieu d'un

La définition de l'état avec this.setState dans la méthode de rendu d'un composant de classe est-elle la même que la définition de l'état dans le corps de fonction d'un composant de fonction avec des crochets?

Techniquement oui, la définition d'un état directement dans la méthode de rendu entraînera le déclenchement du re-rendu en cas de composant de classe provoquant une boucle infinie, ce qui est le cas pour les composants fonctionnels à condition que les valeurs d'état soient différentes. Indépendamment de cela, cela causera toujours un problème car toute autre mise à jour d'état sera annulée en raison du fait que le composant fonctionnel appelle directement la mise à jour d'état

Dans un composant de classe, si nous définissons l'état dans la méthode de rendu, une boucle infinie se produira. Cela est dû au fait que le composant de classe ne se soucie pas que le nouvel état soit le même que l'état précédent. Il ne fait que restituer le rendu sur chaque this.setState.

Oui, il est donc recommandé de ne pas appeler setState directement dans le rendu

Dans un composant de fonction avec des crochets, cependant, la définition de l'état à l'intérieur du corps de la fonction (qui s'exécute lors du re-rendu de la même manière que la méthode de rendu dans les composants de classe) ne serait pas un problème, car le composant de fonction se contente de quitter les re-rendus lorsqu'il voit que l'état est identique à l'état précédent.

Ce n'est pas vrai à 100%, car vous pouvez déclencher la mise à jour de l'état à l'aide de la valeur précédente de sorte que la valeur précédente et la valeur actuelle ne sont pas identiques.

setCount(count => count + 1);

Dans un tel cas, votre composant tombera toujours dans une boucle infinie

15
Shubham Khatri

Ce n'est pas une réponse directe à l'OP, mais lié et peut être utile pour certaines personnes nouvelles à React et/ou Hooks et aux prises avec leurs effets secondaires et le timing de rendu.

Puisqu'il n'a pas encore été mentionné ici: dans les composants fonctionnels plutôt que d'utiliser la fonction mentionnée ci-dessus (voir les commentaires de la réponse acceptée) ShouldComponentUpdate(), qui est uniquement pour les composants basés sur une classe, vous utiliseriez la fonction useEffect() hook. Avec lui, vous pouvez dire à votre composant quand exécuter les effets secondaires ET dans quelles conditions, par ex. lorsque certaines dépendances ont changé.

Dans cet exemple tiré des documents React, uniquement lorsque props.source changé, la fonction sera exécutée.

useEffect(
  () => {
    const subscription = props.source.subscribe();
    return () => {
      subscription.unsubscribe();
    };
  },
  [props.source],
);

React docs: useEffect ()

1
Flip