Abrir Stack.Tab desde un Stack.Screen contenido dentro de un tab con diferentes NavitagionContainer React Native.

Tiempo de lectura: 3 minutos

Os voy a explicar cómo abrir otro tab, dentro de un screen (fuera del tab pero contenido dentro de la pila de ejecución) que ya tenemos contenido en nuestro tab.

Por ejemplo, tenemos la siguiente pantalla y queremos realizar la navegación qué se indica en el vídeo:

Y queremos abrir el tab «Buscar» utilizando el botón de «Pulsa aquí para buscar» qué está contenido dentro de un Screen distinto y añadido en el Tab de «Mis Cursos».

El código es el siguiente:

MenuTab.js

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

import MisCursos from '../screens/MenuMisCursos';
import MenuBuscar from '../screens/MenuBuscar';

//Tab navigator
const Tab = createBottomTabNavigator();

//Componente boton
const Menu = ({ navigation }) => {
    return (
        <View style={[styles.contenedorTotal]}>
            <NavigationContainer style={[styles.contanierSup]} independent={true} >
                <Tab.Navigator initialRouteName="Mis cursos">
                    <Tab.Screen name="Buscar" component={MenuBuscar} />
                    <Tab.Screen name="Mis cursos" component={MisCursos} />
                   />
                </Tab.Navigator>
            </NavigationContainer>
        </View >
    )
};

export default Menu;

Cómo veis en este código, solo hemos creado un Tab Navigator de tipo buttom tabs.

Ahora vamos a crear el Screen de Mis Cursos, qué a su vez va a contener otro NavitagionContainer qué va a montar una pantalla u otra según corresponda.

MenuMisCursos.js

import React, { useState, useEffect } from "react";
import { View, StyleSheet } from "react-native";
import { NavigationContainer, NavigationActions } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';

//Importar pantallas
import Mis_cursos from './Mis_cursos';
import Curso from './Curso';

const Stack = createNativeStackNavigator();

//Crear un componente llamado APP
const MenuMisCursos = ({ navigation }) => {

    return (
        <View style={styles.container}>
            <NavigationContainer independent={true} >
                <Stack.Navigator initialRouteName="Mis cursos">

                    <Stack.Screen name="Mis Cursos" component={Mis_cursos} initialParams={{ navigationTab: { navigation } }} options={{ headerShown: false }} />

                    <Stack.Screen name="Curso" component={Curso} options={{ headerShown: false }} />

                </Stack.Navigator>
            </NavigationContainer>

        </View>
    )
};

//Exporta el componente
export default MenuMisCursos;

const styles = StyleSheet.create({
    container: {
        flex: 1,
    }
});

En este código, creamos un NavigationContainer que contiene dos ventanas. El reto es abrir desde una de estas ventanas, el Tab llamado Buscar (pulsando con un botón).

Para ello lo primero que hago es pasar como parámetro el atributo navigation que llega desde el Navigation.Tab:

{ navigation }

Con esto pasamos el Stack de navegación de la pantalla anterior que corresponde a los tabs.

Queremos navegar dentro del Screen que hemos creado, para ello se lo pasamos como parámetro:

initialParams={{ navigationTab: { navigation } }}

He creado un atributo llamado navigationTab y le paso el parámetro navigation correspondiente al tab.

Ahora solo tendremos que recoger este atributo y utilizarlo dentro del botón correspondiente en la pantalla Mis_cursos.js

import React, { useState } from "react";
import { View, StyleSheet, Text } from "react-native";

//Importar componentes:
import Boton from '../componentes/Boton';

//Componente boton
const MisCursos = ({ navigation, route }) => {

    const { navigationTab } = route.params;
   
   
    return (
        <View style={[styles.contenedorInicio]}>
           
                <View style={[styles.contenedorInicio]}>
                    <Text style={[styles.texto]}>No tienes cursos</Text>
                    <Boton texto="Pulsa aquí para buscar" onPress={() =>  navigationTab.navigation.navigate('Buscar')} />
                </View>
           
        </View>
    )
};

export default MisCursos;

const styles = StyleSheet.create({
    texto: {
        fontSize: 30,
        color: '#000',
    },
    imagen:
    {
        width: 300,
        height: 200,
    },
    padding: {
        paddingBottom: 10,
        paddingTop: 10,
    },
    contenedorInicio: {
        flex: 1,
        display: 'flex',
        alignContent: 'center',
        alignItems: 'center',
    }
});

Para recibir el parámetro sobre el que queremos navegar, se pasa en la función render «route»:

const MisCursos = ({ navigation, route }) => {

*No confundamos navigation, con el objeto anterior ya que este navigation pertenece al Stack.Screen de la pantalla MenuMisCursos.js . El que nos interesa está dentro de route, ya que lo hemos pasado como initialParams.

Para recogerlo usamos este código:

const { navigationTab } = route.params;

Y ahora para utilizar la navegación del Tab qué está en otra pantalla usamos el siguiente código:

navigationTab.navigation.navigate('Buscar')

Con esto podemos navegar desde pantallas distintas.

Nota: El código es de ejemplo y no va a poder ejecutarse porque faltan dependencias y otras clases, pero puede servir para solucionar tu problema.

Deja un comentario