- 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.
Clase 13 de 31 en la ruta Desarrollo movil