Resetear Tab Navigator al cambiar de tab en React Native

Tiempo de lectura: 3 minutos

En este tutorial, aprenderás cómo reiniciar la pila de navegación de un Stack.Navigator dentro de un Tab.Navigator al cambiar entre pestañas. Esto asegura que no se acumulen rutas previas en la navegación, evitando comportamientos inesperados.

Barcos - Pexels

Paso 1: Crear la estructura básica

Comienza configurando un Tab.Navigator que incluya diferentes pestañas, cada una asociada a un Stack.Navigator. Así se pueden tener pilas independientes en cada pestaña.

Estructura básica:

import React from 'react';
import { View, Text, Button } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import { createNativeStackNavigator } from '@react-navigation/native-stack';

const Tab = createBottomTabNavigator();
const Stack = createNativeStackNavigator();

Paso 2: Configurar el Stack.Navigator para cada pestaña

Define pantallas dentro de los Stack.Navigator. Por ejemplo:

const HomeStack = () => (
  <Stack.Navigator>
    <Stack.Screen name="Home" component={HomeScreen} />
    <Stack.Screen name="Details" component={DetailsScreen} />
  </Stack.Navigator>
);

const ProfileStack = () => (
  <Stack.Navigator>
    <Stack.Screen name="Profile" component={ProfileScreen} />
    <Stack.Screen name="Settings" component={SettingsScreen} />
  </Stack.Navigator>
);

Ejemplo de pantallas:

const HomeScreen = ({ navigation }) => (
  <View>
    <Text>Home Screen</Text>
    <Button title="Go to Details" onPress={() => navigation.navigate('Details')} />
  </View>
);

const DetailsScreen = () => (
  <View>
    <Text>Details Screen</Text>
  </View>
);

const ProfileScreen = ({ navigation }) => (
  <View>
    <Text>Profile Screen</Text>
    <Button title="Go to Settings" onPress={() => navigation.navigate('Settings')} />
  </View>
);

const SettingsScreen = () => (
  <View>
    <Text>Settings Screen</Text>
  </View>
);

Paso 3: Configurar el Tab.Navigator con listeners

Usa la propiedad listeners en cada pestaña para reiniciar la pila cuando se cambie a esa pestaña.

Añadir un reset al cambiar de tab:

import { CommonActions } from '@react-navigation/native';

const resetNavigation = (navigation, targetRoute) => {
  navigation.dispatch(
    CommonActions.reset({
      index: 0,
      routes: [{ name: targetRoute }],
    })
  );
};

const App = () => (
  <NavigationContainer>
    <Tab.Navigator>
      <Tab.Screen
        name="HomeTab"
        component={HomeStack}
        listeners={({ navigation }) => ({
          tabPress: () => resetNavigation(navigation, 'Home'),
        })}
      />
      <Tab.Screen
        name="ProfileTab"
        component={ProfileStack}
        listeners={({ navigation }) => ({
          tabPress: () => resetNavigation(navigation, 'Profile'),
        })}
      />
    </Tab.Navigator>
  </NavigationContainer>
);

Paso 4: Probar el comportamiento

  1. Inicia la app y navega dentro de una pestaña (por ejemplo, de «Home» a «Details»).
  2. Cambia a otra pestaña (por ejemplo, «Profile»).
  3. Regresa a la primera pestaña («Home»). Verás que la pila ha sido reiniciada y te lleva directamente a la pantalla inicial («Home»).

Código completo

import React from 'react';
import { View, Text, Button } from 'react-native';
import { NavigationContainer, CommonActions } from '@react-navigation/native';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import { createNativeStackNavigator } from '@react-navigation/native-stack';

const Tab = createBottomTabNavigator();
const Stack = createNativeStackNavigator();

const resetNavigation = (navigation, targetRoute) => {
  navigation.dispatch(
    CommonActions.reset({
      index: 0,
      routes: [{ name: targetRoute }],
    })
  );
};

const HomeScreen = ({ navigation }) => (
  <View>
    <Text>Home Screen</Text>
    <Button title="Go to Details" onPress={() => navigation.navigate('Details')} />
  </View>
);

const DetailsScreen = () => (
  <View>
    <Text>Details Screen</Text>
  </View>
);

const ProfileScreen = ({ navigation }) => (
  <View>
    <Text>Profile Screen</Text>
    <Button title="Go to Settings" onPress={() => navigation.navigate('Settings')} />
  </View>
);

const SettingsScreen = () => (
  <View>
    <Text>Settings Screen</Text>
  </View>
);

const HomeStack = () => (
  <Stack.Navigator>
    <Stack.Screen name="Home" component={HomeScreen} />
    <Stack.Screen name="Details" component={DetailsScreen} />
  </Stack.Navigator>
);

const ProfileStack = () => (
  <Stack.Navigator>
    <Stack.Screen name="Profile" component={ProfileScreen} />
    <Stack.Screen name="Settings" component={SettingsScreen} />
  </Stack.Navigator>
);

const App = () => (
  <NavigationContainer>
    <Tab.Navigator>
      <Tab.Screen
        name="HomeTab"
        component={HomeStack}
        listeners={({ navigation }) => ({
          tabPress: () => resetNavigation(navigation, 'Home'),
        })}
      />
      <Tab.Screen
        name="ProfileTab"
        component={ProfileStack}
        listeners={({ navigation }) => ({
          tabPress: () => resetNavigation(navigation, 'Profile'),
        })}
      />
    </Tab.Navigator>
  </NavigationContainer>
);

export default App;

Deja un comentario