La habilidad para identificar cuándo vale la pena crear un nuevo componente es esencial para desarrollar aplicaciones web profesionales con React o cualquier otra tecnología basada en componentes.
Los Componentes son como fichitas de lego con sus propias funcionalidades y características.
Mientras juntamos nuestros componentes vamos obteniendo resultados más grandes y complejos. Finalmente, el resultado de todos estos componentes es una aplicación sumamente flexible que nos permite añadir, eliminar o actualizar cualquier elemento sin afectar al resto de la aplicación.
Pero aquí entra una duda: ¿Cuándo debemos unir o separar nuestros componentes? ¿Qué características o diferencias debemos analizar para identificar que nuestros componentes no son lo suficientemente flexibles?
Te advierto de una vez: NO hay una respuesta correcta. O más bien, la respuesta correcta es la que más te haga feliz a ti. Ten en cuenta que, a veces, tu felicidad puede requerir algo de sacrificios, sobre todo al principio. Pero no te preocupes. Valdrá la pena.
Vamos a estudiar algunos tipos de componentes que podemos crear, además de algunas arquitecturas y formas de organizar nuestros componentes que funcionan muy bien para diferentes tipos y tamaños de proyectos.
Espero que entiendas un poco sobre qué son los componentes. Si te sientes perdido, te recomiendo comenzar por aquí: Es muy fácil entender Qué es un Componente.
Inicialmente, podemos construir nuestros componentes de forma que tengan lógica o estructura, pero no ambas al mismo tiempo.
Los componentes contenedores controlarán las interacciones con los usuarios, navegador, peticiones a APIs, etc. Los componentes presentacionales se encargarán de la estructura y estilos de nuestra aplicación.
También podemos llamar a nuestros contenedores como Smart Components y a los componentes presentacionales como Dumb Components.
// Contenedor.jsimport React, { useState, useEffect } from ‘react’;
functionContenedor(props) {
const [plant, setPlant] = useState(“”);
useEffect(() => {
const fetchPlant = async () => {
const res = await fetch(props.api);
const plant = await res.json();
setPlant(plant.name);
};
fetchPlant();
}, [props.api]);
const Children = props.children;
return<Childrenplan={plant} />;
}
export default Contenedor;
// Presentacional.jsimport React from ‘react’;
const Presentacional = (props) => (
<divclassName=”plantContainer”><h2className=”plantTitle”>{props.plant}h2>div>
);
exportdefault Presentacional;
De esta forma nos encargarnos de que cada componente tenga una sola responsabilidad. Así sabremos exactamente dónde debemos ir para solucionar un error o añadir una nueva característica.
Además, estas divisiones facilitan la reutilización del código (DRY) y nos ayuda (un poquito) a espantar el código espagueti, eso que suele pasar cuando nuestros componentes son larguísimos y manejan la lógica de 50 cosas diferentes.
Ambos tipos de componentes puedes usar otros componentes para extender su funcionalidad. De hecho, eso es lo que hacen los contenedores con los componentes presentacionales. Esta forma de programar la conocemos como Composición.
Puedes estudiar un poco más a fondo sobre estas prácticas en la siguiente lectura del profe Richard: 3 Patrones Elementales de Desarrollo de Componentes que usamos en React.
También existen diferentes prácticas como las Render Props o las High Order Functions que nos ayudan a facilitar la comunicación entre componentes: Usa Functions as Children (render-props) en Reactjs.
Los Sistemas de Diseño son creación y documentación de los principios y reglas de una marca o producto. Es lo que usan nuestros equipos de desarrollo para transformar diseños, pensamientos e ideas en productos reales y exitosos.
Gracias a los sistemas de diseño nuestros equipos evitan la repetición y pérdida de tiempo en volver a construir elementos y/o flujos de navegación que ya sabemos que funcionan.
También existen las Guías de Estilo. Pero no te confundas. Está muy bien crear guías de estilo, pero no son lo mismo que un sistema de diseño, estos siguen un proceso un poco más complejo. 👍
El Diseño Atómico consiste en construir y organizar nuestros sistemas de diseño desde los componentes más pequeños hasta los más grandes.
Los componentes más pequeños los llamaremos átomos. Un conjunto de átomos formarán una molécula. Muchas moléculas formarán un organismo. Con la suma de estos organismos generamos templates. Y al darle diferente color, contenido y estilos a nuestros átomos obtendremos las diferentes páginas de nuestra aplicación.
Los átomos son los elementos independientes más sencillos de nuestro sistema. Por ejemplo: labels, inputs y botones. Las moléculas son un conjunto de estos elementos. Por ejemplo: un formulario que incluye diferentes labels, inputs y botones.
De esta forma podemos identificar cuándo y con qué objetivo crear nuestros componentes. De hecho, también puede que nos ayude un poco a organizar nuestra estructura de archivos y carpetas.
Referencias:
Antes de empezar, me encantaría darle las gracias al grandioso y espectacular Sergio Xalambrí. Fue Frontend Developer y profesor en Platzi hace algunos años. Nos enseñó muchas cosas. Por ejemplo: cómo organizar y estructurar nuestra aplicación de distintas formas.
Si quieres, podemos darle las gracias por Twitter 😉:
Creamos una carpeta por cada tipo de componentes o elementos de nuestra aplicación.
Tendremos una carpeta para los contenedores. Otra para los componentes presentacionales. Otra para la lógica de conexión a la API. Otra para los custom hooks. Otra para los reducers. Otra para los estilos. Una carpeta para cada todo.
- containers/
- FeatureA.js
- FeatureB.js
- FeatureC.js
- FeatureD.js
- components/
- FeatureA.js
- FeatureB.js
- FeatureC.js
- FeatureD.js
- styles/
- FeatureA.css
- FeatureB.css
- FeatureC.css
- FeatureD.css
- actions/
- ...
- reducers/
- ...
- hooks/
- ...
La ventaja de esta estructura de archivos es la facilidad para organizar nuestra aplicación, sobre todo al principio. Es muy fácil saber dónde está cada componente y dónde irán los próximos.
El problema, como podrás imaginar, es la cantidad de archivos que nos encontraremos al abrir cualquier carpeta. Entre más crece nuestro proyecto, más archivos tendremos en todas nuestras carpetas. Cada vez que queramos añadir o mejorar un componente necesitaremos editar archivos de 50 carpetas diferentes.
Además, nos enfrentamos a un pequeño dilema: debemos negociar entre crear archivos muy pero muy largos o crear muchos pero muchos archivos. 😳
¿Nueva sección de registro?
La estructura visual encomponents/RegisterDumb.js
. La lógica encontainers/RegisterSmart.js
. Y los estilos CSS enstyles/Register.css
.¿Queremos empezar un blog? RIP myself.
La lógica encontainers/Blog.js
ycontainers/BlogPost.js
.
Lo visual encomponents/Blog.js
ycomponents/BlogPost.js
.
Y los estilos enstyles/Blog.js
ystyles/BlogPost.js
.¿Que los artículos tengan comentarios?
😱😱😱😱😱😱😱🏃
Referencias:
Cada feature de nuestra aplicación tendrá su propia carpeta.
En vez de crear una carpeta para cada tipo de componente, cada elemento (lógico o visual) de nuestra aplicación tendrá una carpeta. Y dentro de esa carpeta podemos organizar nuestros archivos como más nos guste, incluso de formas diferentes en cada feature.
- profile
- index.js
- api.js
- hooks.js
- Profile.js
- styles/
- courses
- index.js
- api/
- hooks/
- components/
- containers/
- jobs
- index.js
- firebase.js
- JobsUI.js
- JobsLogic.js
- utils/
- components/
- global
- sharedHooks/
- bodyStyles.css
Para evitar problemas podemos ponernos de acuerdo en una sola forma de comunicar nuestras features con el resto de la aplicación. Por ejemplo: podemos siempre tener un archivo index.js
que única y exclusivamente se encargue de exportar lo que sea que hayamos programado en esa carpeta.
Además de encontrar muchísima claridad en esta estructura de archivos y carpetas, también nos otorga flexibilidad de sobra. Incluso podemos usar diferentes tecnologías para cada feature. 😍
¿Sección de registro? Todo irá en la carpeta de
src/autenticación/
.¿Queremos empezar un blog? Todo irá en la carpeta
src/blog/
.
¿Que los artículos tengan comentarios? Hmmm… Qué bonito se vería en la carpetasrc/blog/comments/
.¿Quieres cambiar la fuente general de la aplicación?
En la carpetasrc/shared/
guardamos todo lo general, lo que usan el resto de features. Busca el archivo de las fuentes CSS por alguna parte ensrc/shared/styles/
.
Recuerda que el éxito de esta flexibilidad en la estructura de archivos y carpetas conlleva una gran responsabilidad. Sé buena persona, alguien responsable. Amarás tu trabajo a más no poder.
Pero si eres irresponsable, tú y todo tu equipo necesitarán una visita diaria al psicólogo. Solo podrás arrepentirte y querer viajar en el tiempo para reclamarte a ti mismo por tu desorden y suciedad.
Referencias:
Creamos una carpeta para cada aplicación.
Esta estructura nos ayuda cuando nuestra aplicación no se divide solo por features, sino también por “subaplicaciones”. Cada subaplicación es independiente de las demás, así que puede manejar la estructura de carpetas que mejor se le adapte.
- Amazon
- Ecommerce
- containers/
- components/
- styles/
- api/
- PrimeVideo
- Browse
- index.js
- MovieThumbnail.js
- Category.js
- SearchForm.js
- containers/
- BrowseByCategory.js
- BrowseBySearch.js
- MovieReproduction/
- MoviePreview/
- MovieAds/
- shared/
- thumbnails/
- icons/
- auth/
- AWS
- Analytics
- CloudSearch/
- RedShift/
- Glue/
- Kinesis/
- Storage
- S3/
- EFS/
- Gateway/
- WindowsFileServer/
- MediaServices
- ElasticTranscoder/
- ElementalVideConnect/
La mejor/peor de todas las estructuras, arquitecturas y organizaciones del universo:
Te invito a tomar el Curso de Arquitecturas CSS donde podrás profundizar en el uso de metodologías y buenas prácticas para organizar tu código CSS (incluyendo varios casos prácticos con React).
Y si quieres construir tu primer gran proyecto con React.js y sus mejores funcionalidades, te recomiendo iniciar con el Curso de React.js.
#NuncaParesDeAprender 🤓💚
¡Que artículo tan cool!
Se debería tratar mucho más el tema de arquitectura en frontend. Creo que ese es uno de los mayores retos del desarrollo web actualmente.
Me encanta la propuesta de estructuración ordenada de carpetas. Me encantaría probar tu metodología.
Excelente articulo la estructura de Feature First (Pods) me pareció muy buena, e interesante de implementarla, pero como mencionas si se tiene un grado de responsabilidad al momento de acomodar las carpetas.
Muy bueno las metodologias voy a probarlas para ver que tan escalable seran para mis proyectos y para los proximos en donde trabajamos 💚.
¡Gracias por todos los recursos! ¡Muy buen artículo!
excelente articulo…
Gracias por compartir esta informacion Juan, gran articulo.
Que buen ejemplo de organización sobre la delimitación de carpetas sobre proyectos.