- Entender el funcionamiento del `Stack Navigator` y el ciclo de navegación (navigate, goBack). - Definir tipos para `RootStackParamList` y pasar parámetros entre pantallas. - Personalizar el header y controlar opciones desde componentes con `navigation.setOptions`.
Actividades prácticas
- Instala las dependencias y crea un
Stackbásico conHome,DetailsyProfile. - Implementa el paso de parámetros a
Detailsy muestraroute.paramsen la UI. - Añade
useLayoutEffectenDetailspara configurar un botón enheaderRight.
Instalación
bash1npm install @react-navigation/native 2npm install react-native-screens react-native-safe-area-context 3npm install @react-navigation/native-stack
Setup Básico
typescript1// App.tsx 2import { NavigationContainer } from "@react-navigation/native"; 3import { createNativeStackNavigator } from "@react-navigation/native-stack"; 4 5type RootStackParamList = { 6 Home: undefined; 7 Details: { id: number; title: string }; 8 Profile: { userId: number }; 9}; 10 11const Stack = createNativeStackNavigator<RootStackParamList>(); 12 13@memo 14export default function App() { 15 return ( 16 <NavigationContainer> 17 <Stack.Navigator 18 initialRouteName="Home" 19 screenOptions={{ 20 headerStyle: { backgroundColor: "#007AFF" }, 21 headerTintColor: "#fff", 22 headerTitleStyle: { fontWeight: "bold" }, 23 }} 24 > 25 <Stack.Screen 26 name="Home" 27 component={HomeScreen} 28 options={{ title: "Inicio" }} 29 /> 30 <Stack.Screen name="Details" component={DetailsScreen} /> 31 <Stack.Screen 32 name="Profile" 33 component={ProfileScreen} 34 options={{ headerShown: false }} 35 /> 36 </Stack.Navigator> 37 </NavigationContainer> 38 ); 39}
Navegación entre Pantallas
typescript1import { NativeStackScreenProps } from "@react-navigation/native-stack"; 2 3// HomeScreen 4type HomeProps = NativeStackScreenProps<RootStackParamList, "Home">; 5 6function HomeScreen({ navigation }: HomeProps) { 7 return ( 8 <View style={styles.container}> 9 <Text style={styles.title}>Home Screen</Text> 10 11 <TouchableOpacity 12 style={styles.button} 13 onPress={() => 14 navigation.navigate("Details", { 15 id: 1, 16 title: "Mi Producto", 17 }) 18 } 19 > 20 <Text style={styles.buttonText}>Ir a Detalles</Text> 21 </TouchableOpacity> 22 23 <TouchableOpacity 24 style={styles.button} 25 onPress={() => navigation.navigate("Profile", { userId: 123 })} 26 > 27 <Text style={styles.buttonText}>Ver Perfil</Text> 28 </TouchableOpacity> 29 </View> 30 ); 31} 32 33// DetailsScreen 34type DetailsProps = NativeStackScreenProps<RootStackParamList, "Details">; 35 36 37 38function DetailsScreen({ route, navigation }: DetailsProps) { 39 const { id, title } = route.params; 40 41 return ( 42 <View style={styles.container}> 43 <Text style={styles.title}>{title}</Text> 44 <Text>ID: {id}</Text> 45 46 <TouchableOpacity 47 style={styles.button} 48 onPress={() => navigation.goBack()} 49 > 50 <Text style={styles.buttonText}>Volver</Text> 51 </TouchableOpacity> 52 53 <TouchableOpacity 54 style={styles.button} 55 onPress={() => navigation.navigate("Home")} 56 > 57 <Text style={styles.buttonText}>Ir a Home</Text> 58 </TouchableOpacity> 59 </View> 60 ); 61}
Header Personalizado
typescript1<Stack.Screen 2 name="Details" 3 component={DetailsScreen} 4 options={({ route }) => ({ 5 title: route.params.title, 6 headerRight: () => ( 7 <TouchableOpacity onPress={() => alert("Favorito")}> 8 <Text style={{ color: "white", marginRight: 10 }}>⭐</Text> 9 </TouchableOpacity> 10 ), 11 headerLeft: () => ( 12 <TouchableOpacity onPress={() => navigation.goBack()}> 13 <Text style={{ color: "white", marginLeft: 10 }}>←</Text> 14 </TouchableOpacity> 15 ), 16 })} 17/>; 18 19// O desde el componente 20function DetailsScreen({ navigation }: DetailsProps) { 21 useLayoutEffect(() => { 22 navigation.setOptions({ 23 headerRight: () => ( 24 <TouchableOpacity onPress={handleShare}> 25 <Text style={{ color: "white" }}>Compartir</Text> 26 </TouchableOpacity> 27 ), 28 }); 29 }, [navigation]); 30 31 return <View>...</View>; 32}
Recursos
1 recurso disponible
Reto de Lectura
Auditoría IA #2 — La pantalla de lista con datos
Genera con tu IA una pantalla de lista con fetch y navegación al detalle, y audítala: performance de lista, async decorativo y params de navegación.
Paso 1 — Genera (10 min). Pídele a tu IA:
"Hazme en React Native con TypeScript una pantalla que cargue usuarios de https://jsonplaceholder.typicode.com/users, los muestre en una lista, y al tocar uno navegue a una pantalla de detalle con React Navigation, con manejo de errores"
Paso 2 — Audita (40 min):
| # | Capa | Pregunta clave |
|---|---|---|
| 1 | Lista (S9) | ¿FlatList o ScrollView+map? ¿keyExtractor? ¿Estilos inline en renderItem? |
| 2 | Async | ¿El catch traga o el error LLEGA a la pantalla (estado de error visible)? ¿Revisa response.ok? ¿Hay estado de loading? |
| 3 | useEffect | ¿Dependencias honestas? ¿Qué pasa si navegas fuera antes de que llegue la respuesta? |
| 4 | Navegación | ¿Qué viaja en los params: el id o el OBJETO usuario completo? ¿Qué implica cada opción si los datos se actualizan? |
| 5 | Tipos | ¿Los params de las rutas están tipados o el navigate es as any? |
| 6 | Sabotaje | Simula red lenta y toca un usuario ANTES de que cargue la lista de nuevo. Cambia la URL a una rota: ¿el usuario se entera? |
Paso 3 — Informe (entregable): prompt, 4+ hallazgos con línea y escenario, corrección verificada en Snack/emulador con el sabotaje aplicado, veredicto de integración.
La solución no se publica. Se revisa en voz alta en el laboratorio, después de que trabajaste el reto. Trae tu diagnóstico escrito: eso es lo que se entrega.
Clase 14 de 32 en la ruta Desarrollo movil