La Raya · app (1): Expo y React Native otra vez, y montar la base en una semana

Publicado el 11/06/2026

Con el backend de La Raya ya sirviendo una API de dominio (su propia serie cuenta esa historia), tocaba la otra mitad: una app móvil para consultar eventos, noticias, gastronomía y turismo de la frontera. Esta entrada es el arranque.

¿Por qué Expo + React Native otra vez?

No por inercia: porque para este proyecto vuelve a ser la respuesta correcta. Quería Android primero (es el mercado), iterar rápido la UI sin pelearme con Gradle cada noche, y poder tener una versión web "gratis" como PWA. Eso es justo lo que da Expo: un solo código, expo-router para navegación, y la posibilidad de exportar a web. Sumé NativeWind v4 (Tailwind en React Native) para estilar rápido y consistente, y un tema propio (lib/theme.ts) con colores, spacing y radios centralizados.

Tener experiencia previa con el stack ayudó a no tropezar dos veces en las mismas piedras. La novedad aquí no era el stack, era el dominio.

La base, en pocos días

El primer empujón fue montar el esqueleto completo:

  • Navegación basada en ficheros con expo-router: cada pantalla es un archivo en app/, las pestañas en app/(tabs)/ (Eventos, Gastronomía, Noticias, Turismo, Perfil), y los detalles como rutas dinámicas (app/evento/[id].tsx, local/[id].tsx…). Sin configurar un router a mano: la estructura de carpetas es el mapa.
  • Auth contra el backend: login/registro con JWT, y un detalle que me importaba — logout de verdad, invalidando el token en el servidor, no solo borrándolo en el cliente.
  • Listados con caché: React Query para cada sección, con sus query keys, manejo de carga y error, y paginación contra la API. Esto te da gratis el refetch, la invalidación y un estado de servidor sano.
  • Imágenes que no rompen la UI: cada tarjeta carga su imagen con un fallback a placeholder si falla (un onError y un diseño que aguanta el hueco). Y un detalle de React que me mordió: declarar los hooks (useState) antes de cualquier return temprano, o el orden de hooks revienta.
  • Percepción de velocidad: skeletons mientras cargan los listados, en vez de un spinner triste. Cambia mucho la sensación.
  • PWA: export web con su manifiesto y favicon, para que la app también viva en el navegador.

Detalles que dan el acabado

Pronto llegaron los toques que separan "demo" de "app":

  • Un splash animado (logo con pulse y fade) para que el arranque no sea un fogonazo en blanco.
  • Un grid de tarjetas adaptable (más columnas en tablet, una en móvil) con imágenes dimensionadas para no descuadrar el layout.
  • Pantalla de detalle de recinto (venue), porque los eventos cuelgan de salas/cines y tenía sentido poder verlas.

Lo que me llevo de este arranque

  • Repetir stack es legítimo si lo eliges, no si lo arrastras. Expo encaja en este proyecto por las mismas razones que en el anterior; haberlo pensado (en vez de asumirlo) es lo que cuenta.
  • La navegación por ficheros es una bendición. Crear una pantalla = crear un archivo. Menos ceremonia, más avanzar.
  • React Query te quita una clase entera de bugs. Estado de servidor, caché e invalidación resueltos; tú te ocupas de la UI.
  • El "acabado" no es opcional. Skeletons, fallback de imágenes y un splash decente cuestan poco y se notan en cada pantalla.

Con la base en pie, el siguiente reto era muy de este proyecto: el idioma. La Raya es bilingüe por naturaleza, y además el backend iba cambiando de forma mientras yo construía encima. De eso va la próxima entrada.