//alexis.dev
Volver al blog
2 min de lectura

Todo proyecto de React Native empieza limpio. Luego llega la décima funcionalidad, se suman tres desarrolladores y de pronto nadie sabe dónde vive la lógica de negocio. Esta es la estructura que uso para evitar que eso pase.

Carpetas por funcionalidad

En lugar de agrupar por rol técnico (components/, hooks/, screens/), agrupa por funcionalidad:

src/
├── features/
│   ├── booking/
│   │   ├── components/
│   │   ├── hooks/
│   │   ├── api.ts
│   │   └── store.ts
│   └── profile/
├── shared/
│   ├── ui/
│   └── lib/
└── app/            # navegación, providers, punto de entrada

Una funcionalidad es dueña de todo lo que necesita. Eliminarla es un rm -rf en lugar de un proyecto de arqueología.

La prueba: ¿puede un desarrollador nuevo encontrar todo el código de "booking" sin preguntarle a nadie? Si la respuesta es sí, la estructura funciona.

Pantallas tontas

Las pantallas componen; no deciden. La lógica de negocio vive en hooks:

export function BookingScreen() {
  const { slots, selectSlot, confirm, isConfirming } = useBooking();
 
  return (
    <Screen>
      <SlotList slots={slots} onSelect={selectSlot} />
      <ConfirmButton onPress={confirm} loading={isConfirming} />
    </Screen>
  );
}

Con la lógica en useBooking, puedes probarla sin renderizar un solo píxel y reutilizarla cuando llegue el inevitable layout para tablet.

Estado: menos global de lo que crees

La mayoría del "estado global" es en realidad caché del servidor. React Query (o SWR) lo maneja mejor de lo que Redux jamás lo hizo. Lo que queda — sesión, tema, un par de flags — cabe en un store pequeño de Zustand.

Tipo de estadoDónde va
Datos del servidorReact Query
Sesión / authZustand
Estado de formulariosreact-hook-form
Estado de navegaciónReact Navigation

Empieza aquí y agrega más ceremonia solo cuando la app lo exija.