Diseñar arquitectura basada en componentes reutilizables

Lectura
15 min~5 min lectura

Concepto clave

Diseñar una arquitectura basada en componentes reutilizables significa estructurar tu aplicación de Expo como un conjunto de bloques modulares e independientes que pueden ensamblarse de diferentes formas. Imagina construir con Lego: cada pieza tiene una función específica y puede usarse en múltiples construcciones sin modificarla. En desarrollo de apps, esto implica crear componentes que sean autocontenidos (manejan su propio estado y lógica cuando es apropiado), desacoplados (no dependen de detalles específicos de otros componentes) y configurables (aceptan props para adaptarse a diferentes contextos).

La clave está en el balance entre reutilización y especialización. Un componente demasiado genérico puede volverse complejo de usar, mientras que uno muy específico limita su reutilización. El objetivo es maximizar la cohesión (cada componente hace una cosa bien) y minimizar el acoplamiento (las dependencias entre componentes). Esto no solo mejora el mantenimiento, sino que acelera el desarrollo al permitir reutilizar código probado en múltiples partes de la app.

Cómo funciona en la práctica

Para implementar esta arquitectura en Expo, sigue un enfoque paso a paso. Primero, identifica patrones comunes en tu UI: botones, tarjetas, listas, formularios. Luego, diseña cada componente pensando en su API pública (las props que expone) y su responsabilidad única. Por ejemplo, un componente Button podría aceptar props como title, onPress, variant (primary, secondary), y disabled, pero no debería saber nada sobre la pantalla donde se usa.

Organiza los componentes en una carpeta components/ con subcarpetas por dominio (ej., ui/ para elementos básicos, features/ para componentes de negocio). Usa composición sobre herencia: en lugar de crear componentes complejos mediante herencia, combina componentes simples. Por ejemplo, un ProductCard podría componerse de Card, Image, Text, y Button. Esto facilita pruebas y cambios, ya que cada pieza es independiente.

Código en acción

Veamos un ejemplo real: refactorizar un componente monolítico en uno reutilizable. Antes, un botón específico para una pantalla:

// Antes: Componente acoplado a una pantalla
import React from 'react';
import { TouchableOpacity, Text, StyleSheet } from 'react-native';

const LoginButton = () => {
  return (
     console.log('Login pressed')}
    >
      Iniciar sesión
    
  );
};

const styles = StyleSheet.create({
  button: { backgroundColor: 'blue', padding: 15, borderRadius: 5 },
  text: { color: 'white', fontSize: 16 }
});

export default LoginButton;

Después, un botón reutilizable:

// Después: Componente reutilizable
import React from 'react';
import { TouchableOpacity, Text, StyleSheet } from 'react-native';

const Button = ({ title, onPress, variant = 'primary', disabled = false }) => {
  const buttonStyles = [
    styles.button,
    variant === 'primary' ? styles.primary : styles.secondary,
    disabled && styles.disabled
  ];
  const textStyles = [
    styles.text,
    variant === 'primary' ? styles.textPrimary : styles.textSecondary,
    disabled && styles.textDisabled
  ];

  return (
    
      {title}
    
  );
};

const styles = StyleSheet.create({
  button: { padding: 15, borderRadius: 5, alignItems: 'center' },
  primary: { backgroundColor: 'blue' },
  secondary: { backgroundColor: 'gray' },
  disabled: { backgroundColor: '#ccc' },
  text: { fontSize: 16, fontWeight: 'bold' },
  textPrimary: { color: 'white' },
  textSecondary: { color: 'black' },
  textDisabled: { color: '#666' }
});

export default Button;

Errores comunes

  • Crear componentes demasiado genéricos: Un componente que intenta hacer todo (ej., un Container con docenas de props) se vuelve difícil de mantener. Solución: Divide responsabilidades en componentes más pequeños y específicos.
  • Acoplar componentes al estado global innecesariamente: Usar Redux o Context para datos que solo un componente necesita. Solución: Mantén el estado local cuando sea posible, y usa estado global solo para datos compartidos.
  • Ignorar la accesibilidad: Componentes reutilizables deben soportar accesibilidad (ej., accessible, accessibilityLabel). Solución: Incluye props de accesibilidad por defecto y documenta su uso.
  • No documentar las props: Otros desarrolladores no sabrán cómo usar el componente. Solución: Usa PropTypes o TypeScript, y añade comentarios claros.
  • Duplicar lógica en componentes similares: Crear múltiples versiones de un botón con pequeñas variaciones. Solución: Extrae la lógica común en hooks personalizados o componentes base.

Checklist de dominio

  1. ¿Cada componente tiene una responsabilidad única y clara?
  2. ¿Las props del componente están bien definidas y documentadas?
  3. ¿El componente es independiente de la pantalla o contexto donde se usa?
  4. ¿Has probado el componente de forma aislada (ej., con Storybook o pruebas unitarias)?
  5. ¿El componente soporta accesibilidad y temas (ej., modo oscuro)?
  6. ¿Has evitado efectos secundarios innecesarios (ej., llamadas API dentro del componente)?
  7. ¿La estructura de carpetas organiza los componentes por dominio o función?

Refactorizar una pantalla de perfil de usuario usando componentes reutilizables

En este ejercicio, tomarás una pantalla de perfil de usuario existente en una app de Expo y la refactorizarás para usar componentes reutilizables. Sigue estos pasos:

  1. Descarga o crea un proyecto Expo básico con una pantalla ProfileScreen.js que muestre: un avatar, nombre, email, biografía, y un botón para editar.
  2. Analiza el código actual e identifica elementos que pueden convertirse en componentes reutilizables (ej., Avatar, InfoCard, ActionButton).
  3. Crea una carpeta components/ y desarrolla al menos 3 componentes reutilizables a partir de la pantalla. Asegúrate de que cada componente acepte props para personalizarlo.
  4. Refactoriza ProfileScreen.js para usar estos nuevos componentes, pasando los datos necesarios como props.
  5. Prueba los componentes en diferentes contextos (ej., usa InfoCard en otra pantalla) para verificar su reutilización.
Pistas
  • Empieza por extraer el componente más simple, como el Avatar, para ganar confianza.
  • Usa PropTypes o TypeScript para definir las props de cada componente y evitar errores.
  • Considera crear un hook personalizado si hay lógica compartida, como formatear fechas o manejar estados de carga.

Evalua tu comprension

Completa el quiz interactivo de arriba para ganar XP.