Organizando tus proyectos en React

Cómo organizar las carpetas de un proyecto escrito con React

Image for post
Image for post

Si ya has estado trabajando en varios proyectos en React muy probablemente habrás visto que existen distintas formas de plantear la organización de carpetas dado que por sí mismo React no plantea una estructura estándar como por ejemplo Angular hace.

En mi opinión, éste es uno de los puntos más importantes a la hora de comenzar a trabajar en un proyecto ya que mejora tanto la productividad (los archivos se encuentran donde se les espera) como la mantenibilidad a largo plazo. Así que en este artículo os contaré algunas de las pautas que he decidido a la hora de organizar mis proyectos con React por si os resultan de utilidad. Como siempre, me encantaría conocer las vuestras porque creo que es un tema en el que cada opinión aporta ideas interesantes.

Nota: este artículo toma como referencia un proyecto basado en React + Redux. Para otro tipo de proyectos es probable que sea necesaria una aproximación distinta.

Estructura inicial

El primer nivel de carpetas (es decir, dentro de la carpeta src) lo he decidido dividir de la siguiente forma:

Image for post
Image for post
Estructura básica

En esta carpeta se encuentran los archivos que contienen las acciones de Redux

Aquí se encontrarán los componentes de nuestra aplicación. En el siguiente apartado desglosaré un poco más la convención que he decidido adoptar para organizar esta carpeta

Las imágenes del proyecto

Los archivos con los reducers de Redux

En el caso de que estéis empleando algún tipo de enrutador (react-router ❤️), en esta carpeta se encontrarán los componentes asociados a cada una de las rutas de nuestra aplicación. He decidido separarlo porque realmente estos componentes son simples contenedores de los que aparecen en la carpeta components y su única misión (probablemente) será la de recabar los parámetros de la URL en la que nos encontremos y pasarlos a los componentes de la carpeta components.

Aquí aparecerán los selectors, es decir, aquellas funciones encargadas de seleccionar del estado de Redux los datos específicos. Si no conocéis este patrón os recomiendo que leáis algún artículo sobre él puesto que es uno de los más útiles cuando integramos Redux en nuestra aplicación (y realmente es muy sencillo de implementar y dará un plus de mantenibilidad y reusabilidad a vuestro proyecto).

Aquí aparecerán los archivos de las funciones, clases y utilidades empleadas dentro de nuestra aplicación como por ejemplo, el objeto encargado de realizar llamadas a la API externa o el sistema de traducciones.

En esta carpeta se encuentran los archivos CSS/SASS de la aplicación en el caso de que estéis empleándolos.

Finalmente, en esta carpeta se localizan los archivos de traducciones si vuestra aplicación es multidioma.

La carpeta components

He decidido dedicar un apartado especial a esta carpeta ya que es aquí donde más puntos de vista y opiniones hay con respecto al tema de este artículo. Mi propuesta es la de crear las siguientes subcarpetas:

Aquí se encontrarán todos los componentes que representan elementos de la interfaz gráfica y que, por tanto, no tienen funcionalidad específica relacionada con nuestra aplicación. Es decir, esta carpeta debería albergar todos nuestros Styled Components (si es que estamos usando esta librería), nuestros conjuntos de iconos así como botones, alertas y spinners de carga. Queda a vuestra elección crear subcarpetas dentro de la carpeta UI. Yo en principio solo recurro a un segundo nivel si empieza a haber demasiados componentes que son del mismo “tipo”, como por ejemplo distintos spinners o distintos tipos de alerta, pero en general no suele ser necesario.

Esta carpeta debe contener los high order components de la aplicación, para que no anden desperdigados por distintas carpetas y que así encontrarlos sea lo más rápido posible.

Si estáis usando redux-form (o cualquier otra librería para gestionar los formularios) mi recomendación es crear esta carpeta para añadir aquellos componentes que representan campos especiales de los formularios, como pueden ser Dropzones, SelectFields (muy recomendable esta librería: react-select) o cualquier otro campo personalizado que sea necesario implementar.

Además de todas las carpetas anteriores, las cuales podemos decir que son fijas en cada aplicación que desarrollo, dentro de components aparecerán x carpetas más, actuando cada una de ellas como una especie de contenedor donde agrupar una determinada entidad de la aplicación (la idea de la tomé de la parte final del artículo enlazado a continuación)

Es decir, si la aplicación contiene un blog, dentro de components aparecerá una carpeta Post, en donde incluiré todos los componentes que encapsulan funcionalidad relacionada con dicho blog (es decir, sus diferentes vistas así como los formularios de haberlos).

Por si no ha quedado claro añado otro ejemplo: el Header de la aplicación también dispondrá de su propia carpeta dentro de components, y dentro de ella aparecerán agrupados componentes como Logo, UserMenu o MainMenu.

Esta sistema, como os decía al principio del artículo, es el que yo he adoptado tras probar distintos métodos y llegar a la conclusión de que, lejos de complicar las cosas, es mejor dejarse guiar por el sentido común y plantear una organización que permita de un primer vistazo saber dónde se encuentra cada elemento.

Por supuesto que este sistema no es nada rígido y seguramente existan mil mejoras y sugerencias que me encantaría leer para irlo puliendo.

Finalmente en lo que respecta al nombrado de componentes y los archivos en los que aparecen yo distingo varios casos:

  1. Si son componentes de uso general, como por ejemplo lo son todos aquellos incluidos dentro de la carpeta UI, yo prefiero nombrar tanto el archivo como el componente exportado con un nombre que represente lo que incluye y sin ningún prefijo o sufijo añadido. Por ejemplo, Icon/Icon.js, Button/Button.js o Alert/Alert.js.
  2. A la hora de nombrar componentes que “jerárquicamente” cuelgan de otros (Header → HeaderMenu) o que son variaciones de una misma entidad (Post → PostTeaser | PostFull) prefiero nombrarlos añadiendo como prefijo el nombre del padre al que pertenecen, ya que así puedo buscarlos dentro del editor mucho más rápido. En este caso, así como en el punto anterior, lo que recomiendo es el uso de Upper Camel Case para el nombre.
  3. Finalmente, teniendo en cuenta que he adoptado la convención de que cada archivo solo contenga una función, salvo casos muy específicos como las actions de Redux o las llamadas a la API, el nombre del fichero se corresponderá con el nombre de la función exportada, escritos ambos en notación Lower Camel Case (transformToNumber).

Con estas 3 reglas creo que tengo cubiertos la mayoría de los casos, consiguiendo tener una estructura coherente y que me permite diferenciar archivos de funciones de archivos de componentes rápidamente.

Bola extra: Ducks

Para aquellos amantes de la organización existe una metodología para organizar las distintas partes que actúan al trabajar con Redux: los ducks,

https://github.com/erikras/ducks-modular-redux

La cual propone agrupar en un solo archivo todas las funciones que intervienen sobre una porción del estado de Redux. Os animo a que le echéis un ojo porque os puede resultar muy útil.

¿Quieres recibir más artículos como este?

Suscríbete a nuestra newsletter:

Written by

Entre paseo y paseo con Simba desarrollo en Symfony y React

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store