Architecture d'application React Redux

Préface



C'est mon premier post sur Habré, alors ne jugez pas trop sévèrement (enfin, ou jugez, mais de manière constructive ).



Je voudrais noter que dans cette approche, le principal avantage pour moi est que nous délimitons et déléguons clairement la logique métier par modules. Un module est responsable d'une chose et de quelque chose de très spécifique. Autrement dit, avec cette approche, pendant le processus de développement, il n'y a pas de pensée: "où est-ce que je ferais mieux (plus correctement) cela ici?" Avec cette approche, il est immédiatement clair où exactement la tâche / le problème doit être résolu.



Structure des fichiers



La structure du projet + est standard. Je vais essayer de vous dire brièvement ce qui est utilisé à partir de ce que l'assemblage lui-même consiste







  • Pour préparer des actions asynchrones, j'utilise le middleware saga - une chose beaucoup plus flexible et puissante concernant le middleware thunk

  • J'ai des composants de style css-modules. En fait, le concept est le même que celui des composants stylisés, mais en quelque sorte, c'est plus pratique pour moi
  • Un intercalaire entre les conteneurs et les composants qui contrôle les accessoires lancés du magasin dans le composant (filtrage, mémorisation et possibilité de manipuler facilement les noms de champ de n'importe quel état de l'application) - resélectionner


Sagas Redux



Documentation Redux sagas



L'essence principale des sagas (et pas seulement) est que nous séparons la logique métier du travail avec les requêtes par modules. Chaque saga est responsable de sa propre partie de l'API. Si j'avais besoin d'obtenir des données utilisateur et d'appeler une action sur leur réception réussie - je le ferais dans un module séparé usersSagas.js



Les principaux facteurs (pour moi) en faveur des sagas sont:

UPD (a ajouté un point sur la promesse-enfer)

  • 1) Le fait que les actions, à l'amiable, ne doivent être que des fonctions qui donnent un objet. Si certaines actions semblent différentes (et c'est ainsi que cela se passe avec l'utilisation de thunk), je voudrais les amener d'une manière ou d'une autre à une forme, car cela ne rentre pas dans un seul concept. Je voudrais déplacer la logique des demandes et travailler avec les données des demandes dans un module séparé - c'est à cela que servent les sagas

  • 2) En règle générale, si nous devons faire plusieurs requêtes utilisant des données issues de réponses à des requêtes précédentes (voulons-nous stocker des données intermédiaires dans le magasin, n'est-ce pas?), Redux-thunk nous invite à faire une nouvelle action dans laquelle nous en appellerons une autre demande d'action asynchrone, dans laquelle 2 autres (par exemple) les mêmes itérations sont effectuées. Cela sent l'enfer de la promesse et a généralement l'air désordonné et, en principe, peu pratique à utiliser (trop d'imbrication), comme pour moi









modules css / composants stylisés



Je vois souvent sur les projets que les gens écrivent des règles pour styliser les composants dans certains modules css courants.



Je suis totalement contre. Le composant est un système isolé. Il doit être aussi réutilisable que possible . Par conséquent, ce serait bien de le styliser séparément.











Sélectionner de nouveau



Les sélecteurs ont plusieurs objectifs:



  • , . , , ( , ). , , . - getFilteredItems,
  • ,
  • . - . - . friends. , . , . , , friends contacts. reselect , , . — .


C'est à cause du dernier point que je me noie pour le fait que nous faisons une réinitialisation à chaque éternuement. Resélectionner - non seulement pour la mémorisation, mais aussi pour un travail plus pratique avec le dessin de l'arborescence d'état de l'application







Composants et conteneurs



Dans l'approche classique de React (sans utiliser de bibliothèques pour stocker le magasin en tant qu'entité distincte), il existe deux types de composants: Presentational et Container-Components. Habituellement (si je comprends bien) ce n'est pas une division stricte des dossiers, mais plutôt une division conceptuelle.



Les composants de présentation sont stupides. Ils ne sont, en fait, que la mise en page et l'affichage des données qui y ont été jetées comme accessoires. (un exemple d'un tel composant peut être trouvé ci-dessus dans les modules css)



Conteneur-Composants - composants qui encapsulent la logique de travailler avec, par exemple, le cycle de vie d'un composant. Ils sont responsables de l'invocation d'une action qui est responsable de la demande de données, par exemple. Ils renvoient un minimum de mise en page, car la mise en page est isolée dans Presentational-Components.



Exemple + -Conteneur-composant: Les







conteneurs Redux sont, en fait, une couche entre le côté redax et les composants de réaction. Dans ceux-ci, nous appelons des sélecteurs et lançons des actions dans les accessoires de réaction du composant.



JE SUIS POUR avoir son propre contenant pour chaque éternuement. Premièrement, cela vous donne plus de contrôle sur les accessoires lancés dans le composant et, deuxièmement, cela vous donne le contrôle des performances en utilisant reselect.



Il arrive souvent que nous devions réutiliser un composant, mais avec différentes parties du magasin. Il s'avère que pour cela, nous devons simplement écrire un autre conteneur et le renvoyer si nécessaire. Autrement dit, la relation plusieurs à un (beaucoup sont des conteneurs, un est un composant. Pour moi, c'est pratique et conceptuel)



Je voudrais également donner un exemple plus fréquent en faveur de la conteneurisation de la plupart des composants.



Nous avons un tableau de données (un tableau d'utilisateurs, par exemple), que nous recevons d'une API. Nous avons également un parchemin infini, que le client ne refusera pas. Nous avons fait défiler vers le bas pendant très longtemps et chargé environ 10k + données. Et maintenant, nous avons changé une propriété d'un utilisateur. Notre application ralentira beaucoup car:



  1. Nous avons attaché le conteneur global à la page entière avec la liste des utilisateurs
  2. Lors du changement d'un champ d'un élément du tableau users, un nouveau tableau avec de nouveaux éléments et indices renvoyés dans le réducteur users
  3. Tous les composants placés dans l'arborescence du composant UsersPage seront redessinés. Y compris chaque composant utilisateur (élément de tableau)


Comment éviter cela?



Nous fabriquons des conteneurs sur



  • tableau avec les utilisateurs
  • élément de tableau (un utilisateur)


Après cela, dans le composant, qui est enveloppé dans un conteneur "array with users", nous retournons le conteneur "array element (one user)" avec la clé (react required prop) lancée là, index



Dans le conteneur "array element (one user)" de mapStateToProps nous sommes le second comme argument, nous prenons les ownProps du composant que le conteneur retourne (parmi eux index). Par index, nous retirons directement du magasin un seul élément du tableau.



De plus, il deviendra beaucoup plus facile d' optimiser le redessinage de l'élément modifié uniquement (le tableau entier est redessiné, car dans le réducteur, nous avons créé une sorte de carte - renvoyant un NOUVEAU tableau avec de nouveaux indices pour chaque élément) - ici, nous serons aidés en resélectionnant le



tableau







conteneur: élément conteneur:







element-selector:







S'il y a des ajouts, je les lirai avec plaisir dans les commentaires.



All Articles