Arquitectura de la aplicación React Redux

Prefacio



Esta es mi primera publicación sobre Habré, así que no juzgues con demasiada dureza (bueno, ni juzgues, pero constructivamente ).



Me gustaría señalar que en este enfoque, la principal ventaja para mí es que delineamos y delegamos claramente la lógica empresarial por módulos. Un módulo es responsable de una cosa y de algo muy específico. Es decir, con este enfoque, durante el proceso de desarrollo, no se piensa: "¿Dónde haría mejor (más correctamente) hacer esto aquí?" Con este enfoque, queda inmediatamente claro dónde se debe resolver exactamente la tarea / problema.



Estructura de archivo



La estructura del proyecto + es estándar. Intentaré contarte brevemente en qué se usa de en qué consiste el ensamblaje en sí







  • Para preparar acciones asincrónicas, utilizo el middleware saga, algo mucho más flexible y potente con respecto al middleware thunk.

  • Tengo componentes de estilo de módulos css. De hecho, el concepto es el mismo que el de los componentes con estilo, pero de alguna manera me resulta más conveniente.
  • Una capa intermedia entre contenedores y componentes que controla los accesorios lanzados desde la tienda al componente (filtrado, memorización y la capacidad de manipular convenientemente los nombres de campo de cualquier parte del estado de la aplicación) - reseleccionar


Sagas redux



Documentación de Redux sagas



La esencia principal de las sagas (y no solo) es que separamos la lógica empresarial de trabajar con solicitudes por módulos. Cada saga es responsable de su propia parte de la API. Si necesitaba obtener datos de usuario y llamar a una acción sobre su recepción exitosa, lo haría en un módulo separado usersSagas.js



Los principales factores (para mí) a favor de las sagas son:

UPD (se agregó un punto sobre la promesa del infierno)

  • 1) El hecho de que las acciones, de forma amistosa, deben ser solo funciones que dan un objeto. Si algunas de las acciones se ven diferentes (y así es como sucede con el uso de procesador), me gustaría llevarlas de alguna manera a una forma, porque de alguna manera esto no encaja en un solo concepto. Me gustaría mover la lógica de las solicitudes y trabajar con datos para solicitudes en un módulo separado: para esto son las sagas

  • 2) Como regla general, si necesitamos realizar varias solicitudes que usen datos de respuestas a solicitudes anteriores (¿y no queremos almacenar datos intermedios en la tienda?), Redux-thunk nos invita a realizar una nueva acción en la que llamaremos a otra solicitud de acción asíncrona, en la que se realizan 2 más (por ejemplo) las mismas iteraciones. Huele a promesa-infierno y generalmente se ve desordenado y, en principio, incómodo de usar (demasiados anidamientos), como para mí









módulos-CSS / componentes con estilo



A menudo veo en proyectos que la gente escribe reglas para diseñar componentes en algunos módulos CSS comunes.



Estoy totalmente en contra. El componente es un sistema aislado. Debería ser lo más reutilizable posible . Por lo tanto, sería bueno diseñarlo por separado.











Volver a seleccionar



Los selectores tienen varios objetivos:



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


Es por el último punto que me estoy ahogando por el hecho de que hacemos un reinicio para cada estornudo. Vuelva a seleccionar, no solo para la memorización, sino también para un trabajo más conveniente con el dibujo del árbol de estado de la aplicación







Componentes y contenedores



En el enfoque clásico de React (sin usar bibliotecas para almacenar la tienda como una entidad separada), hay dos tipos de componentes: Presentacional y Contenedor-Componentes. Por lo general (según tengo entendido), esta no es una división de carpetas estricta, sino más bien una división conceptual.



Los componentes de presentación son estúpidos. De hecho, son solo el diseño y la visualización de los datos que se les arrojaron como accesorios. (un ejemplo de dicho componente se puede encontrar arriba en css-modules)



Contenedor-Componentes : componentes que encapsulan la lógica de trabajar con, por ejemplo, el ciclo de vida de un componente. Son los encargados de invocar una acción que se encarga de solicitar datos, por ejemplo. Devuelven un mínimo de diseño, porque el diseño está aislado en Presentational-Components.



Ejemplo + -Componente de contenedor: Los







contenedores de Redux son, de hecho, una capa entre el lado de redax y los componentes de reacción. En ellos, llamamos a los selectores y lanzamos acciones a los accesorios de reacción del componente.



ESTOY A FAVOR de tener su propio recipiente para cada estornudo. En primer lugar, le da más control sobre los accesorios lanzados al componente y, en segundo lugar, le da control sobre el rendimiento usando reselect.



A menudo sucede que necesitamos reutilizar un componente, pero con diferentes partes de la tienda. Resulta que para esto solo necesitamos escribir otro contenedor y devolverlo donde sea necesario. Es decir, la relación Muchos a uno (muchos son contenedores, uno es un componente. Para mí, es conveniente y conceptualmente)



También me gustaría dar un ejemplo más frecuente a favor de contener la mayoría de los componentes.



Tenemos una matriz de datos (una matriz de usuarios, por ejemplo) que recibimos de alguna API. También tenemos un scroll infinito, que el cliente no va a rechazar. Nos desplazamos hacia abajo durante mucho tiempo y cargamos alrededor de 10k + datos. Y ahora hemos cambiado alguna propiedad de un usuario. Nuestra aplicación se ralentizará mucho porque:



  1. Adjuntamos el contenedor global a toda la página con la lista de usuarios.
  2. Al cambiar un campo de un elemento de la matriz de usuarios, se devuelve una NUEVA matriz con nuevos elementos e índices en el reductor de usuarios
  3. Todos los componentes colocados en el árbol del componente UsersPage se volverán a dibujar. Incluyendo cada componente de usuario (elemento de matriz)


¿Cómo se puede evitar esto?



Hacemos contenedores en



  • matriz con usuarios
  • elemento de matriz (un usuario)


Después de eso, en el componente, que está envuelto en un contenedor "matriz con usuarios", devolvemos el contenedor "elemento de matriz (un usuario)" con la clave (reaccionar prop requerido) arrojada allí, índice



En el contenedor "elemento de matriz (un usuario)" en mapStateToProps somos el segundo como argumento, tomamos los ownProps del componente que devuelve el contenedor (entre ellos index). Por índice, extraemos directamente de la tienda solo un elemento de la matriz.



Además, será mucho más fácil optimizar el rediseño de solo el elemento cambiado (se redibuja toda la matriz, porque en el reductor hicimos algún tipo de mapa que devuelve una NUEVA matriz con nuevos índices para cada elemento); aquí nos ayudarán a volver a seleccionar la



matriz contenedor:







el elemento contenedor:







selector de elementos:







Si hay adiciones, las leeré con gusto en los comentarios.



All Articles