Construir aplicaciones en React que sean fáciles de leer, mantener y modificar no depende de escribir código brillante, sino de aplicar patrones que priorizan la flexibilidad por encima de la elegancia. La composición de componentes es uno de esos patrones fundamentales y, combinada con una buena estrategia de colocación del estado, transforma la manera en que organizamos nuestros proyectos.
¿Qué es la composición de componentes y por qué importa?
La composición de componentes es un principio que establece que cada componente debe cumplir una tarea muy específica, pero sin dictar exactamente cómo se consumirá su resultado [01:00]. En lugar de que un componente decida internamente qué contenido renderiza, le delega esa responsabilidad al componente que lo invoca.
Por ejemplo, en una aplicación como TodoMachine, el componente TodoList podría iterar internamente sobre los elementos y renderizarlos él mismo. Esa sería la forma "por defecto" de pensar. Sin embargo, con composición usamos la propiedad children [02:18]: el componente padre —digamos App— es quien define qué irá dentro de TodoList.
- El componente
TodoList solo provee estructura y estilos.
- El componente
App decide la maquetación interna.
- Cambiar el contenido de
TodoList se vuelve trivial.
Esta separación nos da libertad para reutilizar, integrar y modificar componentes sin efectos colaterales inesperados.
¿Dónde colocar el estado con el principio de máxima cercanía?
Antes de reorganizar los componentes, hay que resolver un detalle crucial: dónde vive el estado. A esto se le conoce como state colocation o colocación del estado [03:05].
¿Qué dice el principio de máxima cercanía a la relevancia?
El estado debe estar tan cerca como sea posible del lugar donde se usa y se actualiza [03:15]. Si un estado solo lo consume TodoHeader, ahí debe vivir. Pero cuando varios componentes lo necesitan, el estado sube al componente padre más cercano que los envuelva a todos, que normalmente es App.
¿Cómo separar componentes stateful y stateless?
Otro principio complementario es no mezclar lógica de estado con maquetación [03:50]. Los componentes stateless solo reciben props y renderizan interfaz. Los componentes stateful gestionan estado propio. Cuando un componente necesita ambas cosas, la solución es dividirlo en dos: uno que maneje el estado y otro que solo se ocupe de la UI.
Aunque a primera vista estos dos principios parecen contradecirse, pueden convivir si se comprenden a fondo [04:15]. La recomendación práctica —atribuida al profesor Richard Kaufman [04:40]— es diseñar desde lo más grande hacia lo más específico: partir de App, identificar las secciones principales (TodoHeader, TodoList) y luego examinar qué vive dentro de cada una.
¿Cómo evitar prop drilling sin usar React Context?
Cuando la comunicación entre App y sus componentes nietos o bisnietos requiere pasar props por cada nivel intermedio, normalmente pensamos en React Context con providers, consumers y el hook useContext [06:05]. Pero la composición ofrece una alternativa sorprendente.
Si App es quien define el contenido de TodoList y TodoHeader mediante children, entonces los componentes internos como TodoCounter, TodoSearch o TodoItem se declaran directamente dentro de App [07:25]. Esto significa que App puede pasarles las props sin intermediarios.
- No hay capas extra de complejidad.
- No necesitas providers ni consumers.
- Leer un solo archivo te muestra la estructura completa de la aplicación.
- Cualquier persona nueva en el proyecto entiende el flujo rápidamente.
¿Cuándo sí conviene usar React Context?
La composición tiene un límite práctico [08:40]. Cuando la aplicación crece tanto que App tendría miles de líneas de código con niveles profundísimos de anidación, mantener todo en un solo archivo se vuelve insostenible. En ese punto, React Context entra en escena para distribuir el estado entre componentes agrupados por secciones.
Lo importante es que la composición no desaparece al incorporar Context [09:20]. Ambos patrones se complementan: Context agrupa secciones grandes de la aplicación, y dentro de cada sección la composición sigue organizando la estructura interna. Incluso en aplicaciones enormes, cada nivel puede aprovechar la composición para mantener el código legible y flexible.
React, de hecho, prefiere el código aburrido —fácil de reemplazar y entender— por encima del código elegante que resulta difícil de modificar [00:10]. Aplicar composición con una estrategia clara de colocación del estado es exactamente eso: código que no impresiona por su ingenio, pero que te permite mover, cambiar y escalar tu aplicación con confianza. ¿Ya aplicas composición en tus proyectos? Comparte en los comentarios cómo organizas tus componentes.