Tab Navigator
Volver a clases
Principiante

Tab Navigator

60 min

- Aprender a configurar `Bottom Tabs` y personalizar iconos, etiquetas y badges. - Entender cómo ocultar headers y combinar `Tabs` con `Stack` para navegación compuesta.

Actividades prácticas

  1. Crea un Tab.Navigator con las pantallas HomeTab, Search, Notifications y Profile.
  2. Añade iconos y tabBarBadge en al menos una pestaña.
  3. Integra MainTabs dentro de un Stack y navega desde una tab a una pantalla del stack.

Bottom Tabs

bash
1npm install @react-navigation/bottom-tabs
typescript
1import { createBottomTabNavigator } from "@react-navigation/bottom-tabs";
2
3type TabParamList = {
4  HomeTab: undefined;
5  Search: undefined;
6  Notifications: undefined;
7  Profile: undefined;
8};
9
10const Tab = createBottomTabNavigator<TabParamList>();
11
12function MainTabs() {
13  return (
14    <Tab.Navigator
15      screenOptions={{
16        tabBarActiveTintColor: "#007AFF",
17        tabBarInactiveTintColor: "gray",
18        headerShown: false,
19      }}
20    >
21      <Tab.Screen
22        name="HomeTab"
23        component={HomeScreen}
24        options={{
25          tabBarLabel: "Inicio",
26          tabBarIcon: ({ color, size }) => (
27            <Text style={{ fontSize: size }}>🏠</Text>
28          ),
29          tabBarBadge: 3,
30        }}
31      />
32
33      <Tab.Screen
34        name="Search"
35        component={SearchScreen}
36        options={{
37          tabBarLabel: "Buscar",
38          tabBarIcon: ({ color, size }) => (
39            <Text style={{ fontSize: size }}>🔍</Text>
40          ),
41        }}
42      />
43
44      <Tab.Screen
45        name="Notifications"
46        component={NotificationsScreen}
47        options={{
48          tabBarLabel: "Notificaciones",
49          tabBarIcon: ({ color, size }) => (
50            <Text style={{ fontSize: size }}>🔔</Text>
51          ),
52          tabBarBadge: 5,
53        }}
54      />
55
56      <Tab.Screen
57        name="Profile"
58        component={ProfileScreen}
59        options={{
60          tabBarLabel: "Perfil",
61          tabBarIcon: ({ color, size }) => (
62            <Text style={{ fontSize: size }}>👤</Text>
63          ),
64        }}
65      />
66    </Tab.Navigator>
67  );
68}

Tabs + Stack Navigator

typescript
1type RootStackParamList = {
2  MainTabs: undefined;
3  Details: { id: number };
4  Settings: undefined;
5};
6
7const Stack = createNativeStackNavigator<RootStackParamList>();
8
9export default function App() {
10  return (
11    <NavigationContainer>
12      <Stack.Navigator>
13        <Stack.Screen
14          name="MainTabs"
15          component={MainTabs}
16          options={{ headerShown: false }}
17        />
18        <Stack.Screen name="Details" component={DetailsScreen} />
19        <Stack.Screen name="Settings" component={SettingsScreen} />
20      </Stack.Navigator>
21    </NavigationContainer>
22  );
23}
24
25// Navegar desde un Tab a un Stack Screen
26function HomeScreen({ navigation }: any) {
27  return (
28    <TouchableOpacity onPress={() => navigation.navigate("Details", { id: 1 })}>
29      <Text>Ver Detalles</Text>
30    </TouchableOpacity>
31  );
32}

Recursos

1 recurso disponible

Reto de Lectura

Reto de LecturaPrincipiante35 min🔴 Sin IA

Reto de Lectura — La navegación amnésica

Una app con tabs que olvida todo: el scroll, el estado, y hasta a qué pantalla ibas. Tres bugs de navegación con la misma raíz.

Los usuarios de esta app reportan: "cada vez que cambio de tab, la lista vuelve al inicio y se borra lo que había escrito". Encuentra la raíz común de los 3 síntomas.

jsx
1function App() {
2  const [usuario, setUsuario] = useState(null);
3
4  // Pantalla definida ADENTRO del componente App 🤔
5  function PantallaBuscar() {
6    const [consulta, setConsulta] = useState("");
7    return (
8      <View style={{ flex: 1 }}>
9        <TextInput value={consulta} onChangeText={setConsulta} />
10        <ResultadosLista consulta={consulta} />
11      </View>
12    );
13  }
14
15  const PantallaPerfil = () => <Perfil usuario={usuario} />;
16
17  return (
18    <NavigationContainer>
19      <Tab.Navigator>
20        <Tab.Screen name="Buscar" component={PantallaBuscar} />
21        <Tab.Screen name="Perfil" component={PantallaPerfil} />
22        <Tab.Screen name="Ajustes">
23          {() => <Ajustes onCambio={setUsuario} />}
24        </Tab.Screen>
25      </Tab.Navigator>
26    </NavigationContainer>
27  );
28}

Preguntas:

  1. ¿Por qué el texto de búsqueda se borra "solo"? Traza qué pasa con PantallaBuscar cada vez que App re-renderiza (por ejemplo, cuando setUsuario corre).
  2. ¿Por qué los tabs NO deberían desmontar la pantalla al cambiar… y aquí sí pasa?
  3. ¿Cuál de las tres formas de declarar pantallas del ejemplo es la correcta y por qué?
  4. Corrige el código completo.