paint-brush
Estructuración de proyectos y nomenclatura de componentes en Reactpor@viniciusdacal
182,436 lecturas
182,436 lecturas

Estructuración de proyectos y nomenclatura de componentes en React

por Vinicius Dacal7m2018/02/28
Read on Terminal Reader
Read this story w/o Javascript

Demasiado Largo; Para Leer

React es solo una biblioteca, no dicta reglas sobre cómo debe organizar y estructurar sus proyectos. En esta publicación, voy a mostrar algunos enfoques que he estado usando durante un tiempo y que he escalado muy bien. Estos enfoques no recrean la rueda, simplemente juntan y refinan lo que tenemos en el mercado. El enfoque anterior minimiza el problema de navegar entre contenedores y carpetas de componentes, pero agrega mucho ruido en el árbol del proyecto. Es importante conocer la diferencia conceptual entre uno y otro.

Companies Mentioned

Mention Thumbnail
Mention Thumbnail
featured image - Estructuración de proyectos y nomenclatura de componentes en React
Vinicius Dacal HackerNoon profile picture

Como React es solo una biblioteca, no dicta reglas sobre cómo debe organizar y estructurar sus proyectos. Esto es bueno, porque nos da la libertad de probar diferentes enfoques y adaptar los que mejor se adapten a nosotros. Por otro lado, esto podría generar cierta confusión para los desarrolladores que se inician en el mundo de React .

En esta publicación, mostraré algunos enfoques que he estado usando durante un tiempo y se han escalado muy bien. Estos enfoques no recrean la rueda, simplemente juntan y refinan lo que tenemos en el mercado.

Recuerda: ¡Nada aquí está escrito en rocas! Puede tomar solo los enfoques que crea que tienen sentido y adaptarlos/cambiarlos para que encajen en su contexto.


Estructura de carpetas

Una de las preguntas que veo a menudo es sobre cómo estructurar archivos y carpetas. En esta publicación, estamos considerando que tiene una estructura mínima, como la creada con create-react-app.

La aplicación create-react genera un proyecto básico para nosotros, que contiene en su raíz los archivos: .gitignore , package.json , README.md , yarn.lock

También genera las carpetas: public y src. El último es donde guardamos nuestro código fuente.

Echa un vistazo a la imagen de abajo, con la estructura descrita:


En esta publicación, nos centraremos en la carpeta src. Todo lo que está fuera de eso, permanecerá intacto.

Contenedores y Componentes

Es probable que ya haya visto la separación entre Contenedores y Componentes de presentación en la carpeta raíz de algún proyecto. quiero decir, dentro

 src
, tienes una carpeta llamada
 components
y otra carpeta llamada
 containers
:

Sin embargo, este tipo de enfoque tiene algunos problemas, como puede ver a continuación:

  • Reglas subjetivas : no tiene reglas claras sobre qué es un contenedor y qué es un componente de presentación . La diferencia entre unos y otros puede ser subjetiva y cuando estás en un equipo, será difícil que todos los desarrolladores estén de acuerdo y juzguen por igual este asunto.
  • No tiene en cuenta el dinamismo de los componentes : incluso cuando decide que un componente encaja en uno de los tipos específicos, es fácil cambiarlo a lo largo de la vida del proyecto, convirtiéndose en otro tipo y obligándolo a moverlo de componentes a contenedores. carpeta y viceversa.
  • Permitir dos componentes con el mismo nombre - Los componentes deben tener nombres declarativos y únicos en la aplicación, para evitar confusiones sobre la responsabilidad de cada uno. Sin embargo, el enfoque anterior abre una brecha al tener dos componentes con el mismo nombre, uno que es un contenedor y otro que es de presentación.
  • Pérdida de productividad: debe navegar constantemente entre contenedores y carpetas de componentes, incluso cuando trabaja en una sola función. Porque es común que una sola característica tenga componentes de los dos tipos.

También hay una variación de ese enfoque, que mantiene esta separación, pero dentro de los módulos.

Imagina que dentro de tu aplicación tienes el módulo Usuario. En su interior, tendrías dos carpetas para separar tus componentes:

El enfoque anterior minimiza el problema de navegar entre carpetas distantes en el árbol del proyecto. Sin embargo, añade mucho ruido. Dependiendo de cuántos módulos tenga su aplicación, terminará con docenas de contenedores y carpetas de componentes.

Por esos motivos, cuando hablamos de organizar carpetas y archivos, es irrelevante dividir nuestros componentes por el concepto de presentación frente a contenedor. Que dicho , vamos a mantener todos nuestros componentes dentro de la carpeta de componentes, excepto las pantallas .

Aun siendo irrelevante separarlos en carpetas, es importante conocer la diferencia conceptual entre uno y otro. Si aún tiene preguntas sobre este tema, le sugiero que lea el artículo: Componentes de presentación y contenedores.

Separando y agrupando el código

Dentro de la carpeta de componentes, agrupamos los archivos por módulo/característica.

En un CRUD de usuario, solo tendríamos el módulo Usuario. Entonces, nuestra estructura sería la siguiente:

Cuando un componente está compuesto por más de un archivo, colocamos este componente y sus archivos en una carpeta con el mismo nombre. Por ejemplo: supongamos que tiene un Form.css que contiene los estilos de Form.jsx. En este caso, su estructura sería así:

Los archivos de prueba permanecen con el archivo que se está probando. En el caso anterior, la prueba para Form.jsx permanecería en su misma carpeta y se llamaría Form.spec.jsx

Componentes de la interfaz de usuario

Más allá de separar los componentes por módulos, también incluimos una carpeta UI dentro de src/components, para guardar todos nuestros componentes genéricos en ella.

Los componentes de la interfaz de usuario son componentes lo suficientemente genéricos como para no pertenecer a un módulo. Son componentes que podría mantener en una biblioteca de código abierto, porque no tienen ninguna lógica comercial de la aplicación específica. Ejemplos de esos componentes son: botones, entradas, casillas de verificación, selecciones, modales, elementos de visualización de datos, etc.

Nombrar componentes

Arriba vimos cómo estructurar carpetas y separar nuestros componentes por módulos. Sin embargo, todavía hay una pregunta: ¿Cómo nombrarlos?

Cuando hablamos de nombrar un componente, se trata del nombre que le damos a la clase o a la const que define el componente:

 class MyComponent extends Component { } const MyComponent () => {};

Como se mencionó anteriormente, el nombre que le demos a los componentes, debe ser claro y único en la aplicación, para que sean más fáciles de encontrar y evitar posibles confusiones.

El nombre de un componente es muy útil cuando necesitamos depurar usando herramientas como React Dev Tools y cuando ocurren errores de tiempo de ejecución en la aplicación. El error siempre viene con el nombre del componente donde ocurrió.

Para nombrar los componentes, seguimos el patrón path-based-component-naming, que consiste en nombrar el componente de acuerdo a su ruta relativa a las carpetas components oa src, en el caso de que se encuentre fuera de la carpeta de componentes. Básicamente, un componente que se encuentra en: componentes/Usuario/

 List.jsx
sería nombrado como
 UserList
.

Cuando el archivo está dentro de una carpeta con el mismo nombre, no necesitamos repetir el nombre. Dicho esto, componentes/Usuario/Formulario/

 Form.jsx
, sería nombrado como
 UserForm
y no como
 UserFormForm
.

El patrón anterior tiene algunos beneficios que podemos ver a continuación:

Facilitar la búsqueda del archivo dentro del proyecto

Si su editor es compatible con la búsqueda difusa, simplemente busque el nombre UserForm para encontrar el archivo correcto:

Si desea buscar el archivo en el árbol de carpetas, puede encontrarlo fácilmente simplemente orientándose por el nombre del componente:

Evite repetir nombres en las importaciones

Siguiendo el patrón, siempre nombrará el archivo de acuerdo con su contexto. Teniendo en cuenta el formulario anterior, sabemos que es un formulario de usuario , pero como ya estamos dentro de la carpeta Usuario , no necesitamos repetir esa palabra en el nombre del archivo del componente. Entonces, lo nombramos solo como Form.jsx

Cuando comencé a trabajar con React , solía poner el nombre completo en el archivo. Sin embargo, eso te hace repetir un nombre muchas veces y la ruta de importación se vuelve demasiado grande. Echa un vistazo a la diferencia entre los enfoques:

En el ejemplo anterior, no puede ver la ventaja de un enfoque a otro. Pero la aplicación crece un poco, es posible ver la diferencia. Mire el ejemplo a continuación, considerando un componente del proyecto en el que trabajo:

Ahora imagine esto multiplicado por 5 o 10 veces en un solo archivo.

Por esa razón, siempre nombramos el archivo de acuerdo con su contexto y el componente de acuerdo con su ubicación relativa a

 components
o
 src
carpeta.

Pantallas

Las pantallas, como ya indica el nombre, serían las pantallas que tenemos en la aplicación.

En un CRUD de usuarios, tendríamos una pantalla para la lista de usuarios, una pantalla para crear un nuevo usuario y una pantalla para editar un usuario existente.

Una pantalla es donde utiliza componentes para componer una página para la aplicación. Idealmente, la pantalla no contendría ninguna lógica y sería un componente funcional.

Mantenemos las pantallas en una carpeta separada en la raíz de src, porque se agruparán de acuerdo con la definición de la ruta y no por módulos:

Teniendo en cuenta que el proyecto usa react-router , mantenemos el archivo Root.jsx dentro del

 screens
carpeta, y definimos en ella todas las rutas de la aplicación.

El código para Root.jsx sería similar a este:

 import React, { Component } from 'react' ; import { Router } from 'react-router' ; import { Redirect, Route, Switch } from 'react-router-dom' ; import ScreensUserForm from './User/Form' ; import ScreensUserList from './User/List' ; const ScreensRoot = () => ( < Router > <Switch> <Route path="/user/list" component={ScreensUserList} /> <Route path="/user/create" component={ScreensUserForm} /> <Route path="/user/:id" component={ScreensUserForm} /> </Switch> </Router> ); export default ScreensRoot;

Fíjate que ponemos todas las pantallas dentro de una carpeta con el mismo nombre de la ruta, usuario/ -> Usuario/. Trate de mantener una carpeta para cada ruta principal y agrupe las subrutas en ella. En este caso, creamos la carpeta Usuario y guardamos en ella la Lista de pantallas y el Formulario de pantalla. Este patrón te ayudará a encontrar fácilmente qué pantalla está representando cada ruta, simplemente echando un vistazo a la url.

Se podría usar una sola pantalla para representar dos rutas diferentes, como hicimos anteriormente con las rutas para crear y editar un usuario.

Puede notar que todos los componentes contienen la pantalla como prefijo en su nombre. Cuando el componente se encuentra fuera de la carpeta de componentes, debemos nombrarlo de acuerdo con su ruta relativa a la carpeta src. Un componente ubicado en src/screens/User/List.jsx debe llamarse ScreensUserList.

Con el Root.jsx creado, nuestra estructura sería la siguiente:


No olvide importar Root.jsx dentro de index.js para que sea el componente raíz de la aplicación.

En caso de que aún tenga dudas sobre cómo debe verse una pantalla, eche un vistazo al ejemplo a continuación, para ver cuál sería la pantalla para el formulario de usuario.

 import React from 'react' ; import UserForm from '../../components/User/Form/Form' ; const ScreensUserForm = ( { match: { params } } ) => ( < div > <h1> {`${!params.id ? 'Create' : 'Update'}`} User </h1>
    <UserForm id={params.id} /> </div> ); export default ScreensUserForm;

Finalmente, nuestra aplicación quedaría estructurada así:

recapitulando

  • Los componentes de presentación y contenedor se mantienen en src/ components
  • Agrupe los componentes por módulo/característica.
  • Mantenga los componentes genéricos dentro de src/ components / UI
  • Mantenga las pantallas simples, con una estructura y un código mínimos.
  • Agrupe las pantallas según la definición de la ruta. Para una ruta /usuario/lista tendríamos una pantalla ubicada en /src/screens/User/List.jsx.
  • Los componentes se nombran de acuerdo con su ruta relativa a componentes o src. Dado eso, un componente ubicado en src/components/User/List.jsx se denominaría UserList. Un componente ubicado en src/screens/User/List se denominaría ScreensUserList.
  • Los componentes que están en una carpeta con el mismo nombre, no repita el nombre en el componente. Teniendo en cuenta eso, un componente ubicado en src/components/User/List/List.jsx se denominaría UserList y NO UserListList.

Conclusión

Los consejos anteriores cubren solo una parte de la organización y estructura de un proyecto. Traté de mantenerlo solo sobre React y dejar Redux para una publicación futura.

¿Y usted? ¿Tienes algún enfoque que te gustaría compartir con nosotros? Escribe una respuesta a continuación, ¡me encantaría leer eso!

¿Disfrutaste la lectura? Ayúdanos a correr la voz dando un me gusta y compartiendo ️️️️ ❤️️

¡No olvides seguirme para recibir notificaciones sobre futuras publicaciones!