Après Mixin
, les composants d’ordre supérieur HOC assument la lourde responsabilité et deviennent la solution recommandée pour une réutilisation logique entre les composants. Les composants de haut niveau révèlent une atmosphère de haut niveau à partir de leurs noms. En fait, ce concept devrait être dérivé des fonctions d’ordre supérieur de JavaScript
. La fonction d’ordre supérieur est une fonction qui accepte une fonction comme entrée ou sortie. On peut penser que le curry est une fonction d’ordre supérieur. La définition des composants d’ordre supérieur est également donnée dans le React
document. Les composants d’ordre supérieur reçoivent des composants et renvoient de nouveaux composants. fonction. La signification spécifique est la suivante : les composants d’ordre élevé peuvent être considérés comme une implémentation de React
motif de décoration. Les composants d’ordre supérieur sont une fonction, et la fonction accepte un composant comme paramètre et renvoie un nouveau composant. Il renverra un amélioré React
Composants. Les composants d’ordre élevé peuvent rendre notre code plus réutilisable, logique et abstrait, peuvent détourner le render
méthode, et peut également contrôler props
et state
.
Comparant Mixin
et HOC
, Mixin
est un mode mixte. En utilisation réelle, Mixin
est toujours très puissant, nous permettant de partager la même méthode dans plusieurs composants, mais il continuera également à ajouter de nouvelles méthodes et attributs aux composants. Le composant lui-même peut non seulement percevoir, mais doit également effectuer les traitements associés (tels que les conflits de noms, la maintenance de l’état, etc.). Une fois que les modules mixtes augmentent, l’ensemble du composant devient difficile à maintenir. Mixin
peut introduire des attributs invisibles, comme dans le Mixin
la méthode utilisée dans le composant de rendu apporte une propriété invisible props
et states
au composant. Mixin
peuvent dépendre les uns des autres et sont couplés les uns aux autres, ce qui n’est pas propice à la maintenance du code. De plus, les méthodes dans différents Mixin
peuvent entrer en conflit les uns avec les autres. Précédemment React
officiellement recommandé d’utiliser Mixin
pour résoudre des problèmes liés à des préoccupations transversales, mais parce que l’utilisation Mixin
peut causer plus de problèmes, la recommandation officielle est désormais d’utiliser HOC
. Composant d’ordre élevé HOC
appartiennent à l’idée de functional programming
. Les composants encapsulés ne connaîtront pas l’existence de composants d’ordre élevé, et les composants renvoyés par les composants d’ordre élevé auront un effet d’amélioration fonctionnelle sur les composants d’origine. Basé sur ceci, React
recommande officiellement l’utilisation de composants de haut niveau.
Bien que HOC
n’a pas tant de problèmes fatals, il a aussi quelques défauts mineurs :
- Restriction d’évolutivité :
HOC
ne peut pas remplacer complètementMixin
. Dans certains scénarios,Mixin
je peux maisHOC
ne peut pas. Par exemple,PureRenderMixin
parce queHOC
ne peut pas accéder auState
des sous-composants de l’extérieur, et en même temps filtrer les mises à jour inutiles viashouldComponentUpdate
. Donc,React
Après avoir soutenuES6Class
,React.PureComponent
est fourni pour résoudre ce problème. Ref
problème de transfert :Ref
est coupé. Le problème du transfert deRef
C’est assez gênant sous les couches d’emballage. La fonctionRef
peut en atténuer une partie (permettantHOC
pour en savoir plus sur la création et la destruction de nœuds), donc leReact.forwardRef API
L’API a été introduite plus tard.WrapperHell
:HOC
est inondé, etWrapperHell
apparaît (il n’y a aucun problème qui ne puisse être résolu par une seule couche, s’il y en a, alors deux couches). L’abstraction multicouche augmente également la complexité et le coût de la compréhension. C’est le défaut le plus critique. DansHOC
mode Il n’y a pas de bonne solution.
Exemple
Plus précisément, un composant d’ordre supérieur est une fonction dont le paramètre est un composant et la valeur de retour est un nouveau composant. Un composant convertit props
dans une UI
mais un composant d’ordre supérieur convertit un composant en un autre composant. HOC
est très courant dans React
bibliothèques tierces, telles que Redux
c’est connect
et Relay
c’est createFragmentContainer
.
Il faut faire attention ici, n’essayez pas de modifier le prototype du composant dans le HOC
de quelque manière que ce soit, mais doit utiliser la méthode de combinaison pour réaliser la fonction en emballant le composant dans le composant conteneur. Dans des circonstances normales, il existe deux manières d’implémenter des composants d’ordre élevé :
- Agent immobilier
Props Proxy
. - Héritage inversé
Inheritance Inversion
.
Agent immobilier
Par exemple, nous pouvons ajouter un id
valeur d’attribut au composant entrant. Nous pouvons ajouter un props
à ce composant via des composants d’ordre élevé. Bien entendu, nous pouvons également opérer sur le props
dans le WrappedComponent
composant dans JSX
. Notez qu’il ne s’agit pas de manipuler les données entrantes. WrappedComponent
classe, nous ne devons pas modifier directement le composant entrant, mais pouvons opérer dessus dans le processus de combinaison.
Nous pouvons également utiliser des composants d’ordre élevé pour charger l’état des nouveaux composants dans les composants packagés. Par exemple, nous pouvons utiliser des composants d’ordre élevé pour convertir des composants non contrôlés en composants contrôlés.
Ou notre objectif est de l’envelopper avec d’autres composants pour atteindre l’objectif de mise en page ou de style.
Héritage inversé
L’héritage inversé signifie que le composant renvoyé hérite du composant précédent. En héritage inverse, on peut faire beaucoup d’opérations, modifier state
, props
et même retourner le Element Tree
. Il y a un point important dans l’héritage inverse : l’héritage inverse ne peut pas garantir que l’arborescence complète des sous-composants est analysée. Cela signifie que si l’arborescence des éléments analysés contient des composants (function
tapez ou Class
type), les sous-composants du composant ne sont plus manipulables.
Lorsque nous utilisons l’héritage inverse pour implémenter des composants d’ordre élevé, nous pouvons contrôler le rendu via le détournement de rendu. Plus précisément, nous pouvons contrôler consciemment le processus de rendu de WrappedComponent
pour contrôler les résultats du contrôle de rendu. Par exemple, nous pouvons décider de restituer ou non les composants en fonction de certains paramètres.
On peut même détourner le cycle de vie du composant d’origine en le réécrivant.
Puisqu’il s’agit en réalité d’une relation d’héritage, on peut lire le props
et state
du composant. Si nécessaire, nous pouvons même ajouter, modifier et supprimer le props
et state
. Bien entendu, le principe est que les risques provoqués par la modification doivent être contrôlés par vous-même. Dans certains cas, nous pouvons avoir besoin de transmettre certains paramètres pour les attributs d’ordre supérieur, nous pouvons alors transmettre les paramètres sous forme de curry et coopérer avec les composants d’ordre supérieur pour terminer l’opération similaire à la fermeture du composant.
note
Ne changez pas les composants d’origine
N’essayez pas de modifier le prototype du composant dans HOC
ou modifiez-le d’une autre manière.
Cela aurait des conséquences indésirables. La première est que le composant d’entrée ne peut plus être utilisé comme avant HOC
renforcement. Ce qui est plus grave c’est que si vous en utilisez un autre HOC
cela modifie également componentDidUpdate
pour le valoriser, le précédent HOC
sera invalide, et ceci HOC
ne peut pas être appliqué à des composants fonctionnels qui n’ont pas de cycle de vie.
Modification du HOC
du composant entrant est une mauvaise abstraction, et l’appelant doit savoir comment ils sont implémentés pour éviter les conflits avec d’autres HOC
. HOC
ne doit pas modifier les composants entrants, mais doit utiliser une combinaison de composants pour réaliser des fonctions en empaquetant les composants dans des composants conteneurs.
Accessoires de filtre
HOC
ajoute des fonctionnalités aux composants et ne devrait pas modifier de manière significative la convention elle-même. Les composants renvoyés par HOC
doit conserver des interfaces similaires avec les composants d’origine. HOC
devrait transmettre de manière transparente props
qui n’ont rien à voir avec lui-même, et la plupart HOC
devrait inclure un render
méthode similaire à la suivante.
Composabilité maximale
Pas tout HOCs
sont identiques. Parfois, il n’accepte qu’un seul paramètre, qui est le composant packagé.
const NavbarWithRouter = withRouter(Navbar);
HOC
peut généralement recevoir plusieurs paramètres. Par exemple, dans Relay
HOC reçoit en outre un objet de configuration pour spécifier la dépendance aux données du composant.
const CommentWithRelay = Relay.createContainer(Comment, config);
Les signatures HOC les plus courantes sont les suivantes : connect est une fonction d’ordre supérieur qui renvoie des composants d’ordre supérieur.
Ce formulaire peut sembler déroutant ou inutile, mais il possède une propriété utile, comme le paramètre unique HOC
renvoyé par le connect
la fonction a la signature Component => Component
, et les fonctions avec le même type de sortie et le même type d’entrée peuvent être facilement combinées. Les mêmes attributs permettent également connect
et autre HOCs
assumer le rôle de décorateur. De plus, de nombreuses bibliothèques tierces fournissent des fonctions d’outil de composition, notamment lodash
, Redux
et Ramda
.
N’utilisez pas HOC dans la méthode de rendu
React
c’est diff
L’algorithme utilise l’identifiant du composant pour déterminer s’il doit mettre à jour le sous-arbre existant ou le supprimer et monter le nouveau sous-arbre. Si le composant est revenu du render
est le même que le composant du rendu précédent ===
, React
passes Le sous-arbre est distingué du nouveau sous-arbre pour mettre à jour le sous-arbre de manière récursive, et s’ils ne sont pas égaux, le sous-arbre précédent est complètement déchargé.
Habituellement, vous n’avez pas besoin d’en tenir compte lorsque vous l’utilisez, mais c’est très important pour HOC
car cela signifie que vous ne devez pas postuler HOC
à un composant dans le render
méthode du composant.
Ce n’est pas seulement un problème de performances. Le remontage du composant entraînera la perte de l’état du composant et de tous ses sous-composants. Si la HOC
est créé en dehors du composant, le composant ne sera créé qu’une seule fois. Alors chaque fois que tu render
ce sera le même composant. De manière générale, cela correspond à vos performances attendues. Dans de rares cas, vous devez appeler HOC
dynamiquement, vous pouvez l’appeler dans la méthode de cycle de vie du composant ou dans son constructeur.
Assurez-vous de copier les méthodes statiques
Il est parfois utile de définir des méthodes statiques sur React
Composants. Par exemple, le Relay
le conteneur expose une méthode statique getFragment
pour faciliter la composition de GraphQL
fragments. Mais quand tu postules HOC
à un composant, le composant d’origine sera empaqueté avec un composant conteneur, ce qui signifie que le nouveau composant n’a aucune méthode statique du composant d’origine.
Pour résoudre ce problème, vous pouvez copier ces méthodes dans le composant conteneur avant de revenir.
Mais pour ce faire, vous devez savoir quelles méthodes doivent être copiées. Vous pouvez utiliser hoist-non-react-statics
pour copier automatiquement tous les non-React
méthodes statiques.
En plus d’exporter des composants, une autre solution réalisable consiste à exporter en plus cette méthode statique.
Les références ne seront pas transmises
Bien que la convention des composants de haut niveau soit de props
au composant emballé, cela ne s’applique pas à refs
parce que ref
n’est pas réellement un prop
tout comme un key
il est spécifiquement géré par React
. Si la ref
est ajouté à la composante de retour du HOC
le ref
la référence pointe vers le composant conteneur, et non vers le composant packagé. Ce problème peut être explicitement transmis au composant interne via le React.forwardRefAPI
refs
.