51 votes

Un composant apatride sera-t-il rendu à nouveau si ses props n'ont pas changé ?

Une chose que j'ai apprise à propos de React est que si les props d'un composant ne changent pas, alors React ne prend pas la peine de refaire le rendu du composant. Est-ce que c'est aussi vrai pour les composants sans état ? Ou se comportent-ils plus comme des fonctions "stupides" et sont exécutés à chaque fois ?

Par exemple, si j'avais :

import StatelessComponent from '../StatelessComponent';

export default class DocumentsTable extends React.Component {
  state = {
    something: 'foobar',
  };

  render() {
    return (
      <div>
        { this.state.something }
        <StatelessComponent theOnlyProp='baz'>
      </div>
    )
  }
};

Lorsque this.state.something met à jour sa valeur, fait <StatelessComponent> a été rendu à nouveau ? Ou est-il assez "intelligent" pour voir que ses accessoires n'ont pas changé, comme les autres composants React ?

80voto

Lyubomir Points 10274

MISE À JOUR 25.10.2018

Depuis React 16.6, vous pouvez utiliser React.memo pour les composants fonctionnels afin d'éviter un nouveau rendu, de manière similaire à PureComponent pour les composants de classe :

const MyComponent = React.memo((props) => {
  return (
    /* markup */
  );
});

De plus, memo ne optimisation interne .

Et contrairement à une implémentation de composant d'ordre supérieur de type userland memo(), celle intégrée à React peut être plus efficace en évitant une couche de composant supplémentaire. Citation en bloc


ANCIENNE RÉPONSE

Oui, ils refont toujours le rendu 1 (sauf si vous utilisez React.memo comme expliqué ci-dessus) si setState() est appelé dans le composant lui-même ou dans l'un de ses parents, car les composants fonctionnels sans état ne portent pas d'icône shouldComponentUpdate . En fait, chaque composant React est rendu à nouveau. 1 à moins qu'ils ne mettent en œuvre shouldComponentUpdate .


Il est important de noter que en appelant render() ne signifie pas que les nœuds du DOM sont manipulés de quelque façon que ce soit. . Le site render sert juste la méthode algorithme de différenciation pour décider quels DOM Nodes doivent vraiment être attachés / détachés. Notez que render() n'est pas coûteux, ce sont les manipulations du DOM qui le sont. . Ils ne sont exécutés que si render() renvoie des arbres virtuels différents.

De la part de React documentation

Juste pour être clair, rerender dans ce contexte signifie appeler render pour tous les composants, cela ne signifie pas que React va les démonter et les remonter. Il va seulement appliquer les différences en suivant les règles énoncées dans les sections précédentes.

Ne t'inquiète pas et laisse render() soit appelé, sauf si votre composant est énorme, alors il est préférable d'utiliser un composant à état qui implémente shouldComponentUpdate() .

Regardez aquí pour une discussion intéressante.

1 signifie que render() du composant est appelée, et non que le nœud DOM sous-jacent est manipulé.

2 votes

Merci pour la mention de .memo . C'est exactement ce dont j'avais besoin.

1voto

Aniruddh Agarwal Points 567

Vous voyez, react ne se présente pas seulement si les props sont changés, il se présente même s'il y a un changement d'état. Dans votre cas, le composant se réactualise lorsque votre état change. La façon dont react fonctionne est basée sur un algorithme nommé Réconciliation Cet algorithme compare votre DOM virtuel avec le DOM réel et s'il voit un changement, il rend à nouveau votre DOM réel en le remplaçant par votre DOM virtuel, de sorte que tout changement d'état entraîne un nouveau rendu de l'ensemble du composant.

1voto

Patrick Desjardins Points 51478

Un composant apatride sera-t-il rendu à nouveau si ses props n'ont pas changé ?

Oui. Apatride La fonction render sera appelée même si rien n'a changé. Cependant, dans la phase de réconciliation, React comparera le DOM virtuel (généré par la fonction de rendu) avec le DOM existant. Ceci est loin dans le pipeline, donc pas idéal si la fonction de rendu était coûteuse à calculer.

A Composant pur a une comparaison superficielle par défaut de la propriété et aurait arrêté l'exécution du rendu. Voir le Composant pur comme une normale classe composant React qui a un shouldComponentUpdate qui comparent avec un triple égal les propriétés existantes et la nouvelle.

Ceci étant dit, vous pouvez envelopper votre Composant apatride en un Composant pur en utilisant Recompose.pure ( https://github.com/acdlite/recompose/blob/master/docs/API.md#pure ) qui s'exécutera automatiquement, comme le Composant pur , une comparaison superficielle sans compromis sur la syntaxe courte de la Composant apatride .

import StatelessComponent from '../StatelessComponent';   
const PureChildFromStatelessComponent = Recompose.pure(StatelessComponent);
// ... 
<PureChildFromStatelessComponent ... />

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