Quand utiliser les composants React basés sur la classe ES6 par rapport aux composants ES6 React fonctionnels?

213

Après avoir passé du temps à apprendre React, je comprends la différence entre les deux principaux paradigmes de création de composants.

Ma question est quand dois-je utiliser lequel et pourquoi? Quels sont les avantages / compromis de l'un sur l'autre?


Classes ES6:

import React, { Component } from 'react';

export class MyComponent extends Component {
  render() {
    return (
      <div></div>
    );
  }
}

Fonctionnel:

const MyComponent = (props) => {
    return (
      <div></div>
    );
}

Je pense fonctionnel chaque fois qu'il n'y a aucun état à manipuler par ce composant, mais est-ce bien cela?

Je suppose que si j'utilise des méthodes de cycle de vie, il serait préférable d'utiliser un composant basé sur une classe.

omarjmh
la source
7
Il semble que vous connaissiez déjà la réponse.
Felix Kling
2
Si vous disposez uniquement d'un composant avec une méthode de rendu, vous pouvez le transformer en forme fonctionnelle. Si vous avez besoin de quelque chose de plus que la fonction de rendu sans état, utilisez des classes
just-boris
2
Pour être encore plus concis, essayez ceci:const MyComponent = (props) => <div>...</div>
Viliam Simko
1
Je n'utilise jamais de fonctionnel si cela peut être évité. Parce que je finis inévitablement par avoir besoin de refactoriser en classe sur la route. Et puis souvent besoin de refactoriser à nouveau fonctionnel après cela.
keithjgrant
En 2020, l'approche correcte consiste à utiliser des composants fonctionnels dans la mesure du possible, car ils prennent en charge les crochets, et les crochets sont (en termes de performances et d'architecture) meilleurs que les alternatives.
polkovnikov.ph

Réponses:

162

Vous avez la bonne idée. Optez pour la fonctionnalité si votre composant ne fait pas beaucoup plus que de prendre en charge certains accessoires et de rendre. Vous pouvez les considérer comme des fonctions pures car elles seront toujours restituées et se comporteront de la même manière, étant donné les mêmes accessoires. De plus, ils ne se soucient pas des méthodes de cycle de vie ou n'ont pas leur propre état interne.

Parce qu'ils sont légers, l'écriture de ces composants simples en tant que composants fonctionnels est assez standard.

Si vos composants ont besoin de plus de fonctionnalités, comme garder l'état, utilisez plutôt des classes.

Plus d'informations: https://facebook.github.io/react/docs/reusable-components.html#es6-classes


EDIT : Une grande partie de ce qui précède était vraie, jusqu'à l'introduction de React Hooks.

  • componentDidUpdatepeut être répliqué avec useEffect(fn), où fnest la fonction à exécuter lors du rendu.

  • componentDidMountLes méthodes peuvent être répliquées avec useEffect(fn, []), où fnest la fonction à exécuter lors du rendu, et []est un tableau d'objets pour lesquels le composant sera rendu, si et seulement si au moins un a changé de valeur depuis le rendu précédent. Comme il n'y en a pas, useEffect()s'exécute une fois, sur la première monture.

  • statepeut être répliqué avec useState(), dont la valeur de retour peut être déstructurée en une référence de l'état et une fonction qui peut définir l'état (c.-à const [state, setState] = useState(initState)-d.). Un exemple pourrait expliquer cela plus clairement:

const Counter = () => {
  const [count, setCount] = useState(0)

  const increment = () => { 
    setCount(count + 1);
  }

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={increment}>+</button>
    </div>
  )
}

default export Counter

En ce qui concerne la recommandation sur le moment d'utiliser la classe sur les composants fonctionnels, Facebook recommande officiellement d' utiliser des composants fonctionnels dans la mesure du possible . En passant, j'ai entendu un certain nombre de personnes discuter de ne pas utiliser de composants fonctionnels pour des raisons de performances, en particulier que

"Les fonctions de gestion des événements sont redéfinies par rendu dans les composants fonctionnels"

Bien que cela soit vrai, veuillez considérer si vos composants sont vraiment rendus à une vitesse ou un volume tels que cela vaudrait la peine.

Si tel est le cas, vous pouvez empêcher la redéfinition des fonctions à l'aide de useCallbacket useMemohooks. Cependant, gardez à l'esprit que cela peut rendre votre code (microscopiquement) moins performant .

Mais honnêtement, je n'ai jamais entendu parler de la redéfinition des fonctions comme un goulot d'étranglement dans les applications React. Les optimisations prématurées sont à l'origine de tous les maux - inquiétez-vous quand c'est un problème

Jeff Cousins
la source
Qu'en est-il des fonctionnalités qui ne gardent pas l'état, mais qui sont étroitement couplées au composant, par exemple déterminer un attribut dynamique pour le rendu.
Dennis
Ceci est le meilleur article sur la différence entre les deux types de composants dans React: code.tutsplus.com/tutorials/…
Arian Acosta
5
Depuis React 16.8, vous pouvez utiliser l'état dans un composant fonctionnel, via le useStatehook.
Greg
À partir de React 16.8, vous pouvez presque tout faire dans les composants fonctionnels, et tous les effets peuvent enfin être modularisés avec un impact minimal sur les performances.
polkovnikov.ph
1
Où avez-vous trouvé les informations où Facebook officially recommends using functional components wherever possible?
johannchopin
40

Essayez toujours d'utiliser des fonctions sans état (composants fonctionnels) dans la mesure du possible. Il existe des scénarios dans lesquels vous devrez utiliser une classe React régulière:

  • Le composant doit maintenir son état
  • Le composant est trop rendu et vous devez contrôler cela via shouldComponentUpdate
  • Vous avez besoin d'un composant conteneur

METTRE À JOUR

Il y a maintenant une classe React appelée PureComponentque vous pouvez étendre (au lieu de Component) qui implémente la sienne shouldComponentUpdatequi prend en charge la comparaison des accessoires peu profonds pour vous. Lire la suite

ffxsam
la source
43
Always try to use stateless functions (functional components) whenever possible.J'ai lu que dix personnes l'ont dit. Aucun d'eux n'a encore expliqué pourquoi.
Rotareti
25
In an ideal world, most of your components would be stateless functions because in the future we’ll also be able to make performance optimizations specific to these components by avoiding unnecessary checks and memory allocations. This is the recommended pattern, when possible.Plus d'infos: facebook.github.io/react/docs/…
Diogo Cardoso
2
@rotareti Je ne sais pas si vous pensez avoir obtenu une réponse à votre question, mais les fonctions pures sont beaucoup plus simples à comprendre, à tester et à maintenir. Étant donné les mêmes paramètres, ils rendent toujours la même chose. Les composants qui conservent leur état et changent lorsque des événements de cycle de vie se produisent sont plus difficiles à comprendre. Cela ne veut pas dire qu'ils ne sont pas parfois nécessaires, mais j'espère qu'il est clair que si leurs avantages ne sont pas nécessaires, tout ce qu'ils font, c'est ajouter un passe-partout indésirable et des frais généraux sans avantages.
door_number_three
Vous souhaiterez également créer une classe Component si vous avez vos propres définitions de gestionnaire d'événements. De cette façon, vous pouvez pré-lier ces gestionnaires d'événements au composant dans le constructeur au lieu de créer une nouvelle fonction sur chaque rendu. Notez que cela n'est pas nécessaire si tous vos gestionnaires d'événements proviennent d'accessoires.
Dobes Vandermeer
Notez que la recommandation Facebook citée n'existe plus (voir mon commentaire ci-dessus).
Garrett
34

MISE À JOUR mars 2019

https://overreacted.io/how-are-function-components-different-from-classes/

MISE À JOUR février 2019:

Avec l'introduction des hooks React , il semble que les équipes React souhaitent que nous utilisions des composants fonctionnels dans la mesure du possible (ce qui suit mieux la nature fonctionnelle de JavaScript).

Leur motivation:

1.) Its hard to reuse stateful logic between components
2.) Complex components become hard to understand
3.) Classes confuse both people and machines

Un composant fonctionnel avec des crochets peut faire presque tout ce qu'un composant de classe peut faire, sans aucun des inconvénients mentionnés ci-dessus.

Je recommande de les utiliser dès que possible.

Réponse originale

Les composants fonctionnels ne sont pas plus légers que les composants basés sur des classes, "ils fonctionnent exactement comme des classes". - https://github.com/facebook/react/issues/5677#issuecomment-241190513

Le lien ci-dessus est un peu daté, mais la documentation de React 16.7.0 indique que les composants fonctionnels et de classe:

"sont équivalents du point de vue de React." - https://reactjs.org/docs/components-and-props.html#stateless-functions

Il n'y a essentiellement aucune différence entre un composant fonctionnel et un composant de classe qui implémente simplement la méthode de rendu, autre que la syntaxe.

À l'avenir (en citant le lien ci-dessus) "nous [Réagissons] pourrions ajouter de telles optimisations."

Si vous essayez d'améliorer les performances en éliminant les rendus inutiles, les deux approches offrent un support. memopour les composants fonctionnels et PureComponentpour les classes.

- https://reactjs.org/docs/react-api.html#reactmemo

- https://reactjs.org/docs/react-api.html#reactpurecomponent

C'est vraiment comme tu veux. Si vous voulez moins de passe-partout, passez au fonctionnel. Si vous aimez la programmation fonctionnelle et que vous n'aimez pas les classes, rendez-vous fonctionnel. Si vous souhaitez une cohérence entre tous les composants de votre base de code, optez pour les classes. Si vous en avez assez de refactoriser les composants fonctionnels en composants basés sur les classes lorsque vous avez besoin de quelque chose comme ça state, allez avec les classes.

Galupuf
la source
1
Je pense que rendre chaque composant étendre React.Component rend le code plus lisible, en particulier pour les nouvelles personnes. C'est bien quand vous voyez un composant créé de la même manière à chaque fois. Comme l'a dit @Galupuf, les composants simples n'ont qu'une seule méthode appelée "render ()". Il est également agréable de tout faire étendre React.Component car lorsque vous voulez commencer à lier "this", avoir un état, etc. vous n'avez pas besoin de tout refactoriser, vous pouvez simplement ajouter ce dont vous avez besoin.
jeffski13
10

Depuis React 16.8, le terme composants fonctionnels sans état est trompeur et doit être évité car ils ne le sont plus ( React.SFC obsolète , Dan Abramov sur React.SFC ), ils peuvent avoir un état, ils peuvent avoir des crochets (qui agissent comme méthodes de cycle de vie) ainsi, elles se chevauchent plus ou moins avec les composants de la classe

Composants basés sur les classes

Composants fonctionnels:

Pourquoi je préfère les composants Funtional

  • React fournir le crochet de useEffect qui est une façon très claire et concise de combiner componentDidMount, componentDidUpdateet les componentWillUnmountméthodes du cycle de vie
  • Avec des crochets, vous pouvez extraire une logique qui peut être facilement partagée entre les composants et testable
  • moins de confusion sur la portée

Réagissez à la motivation de l'utilisation des crochets (c'est-à-dire des composants fonctionnels).

Karim
la source