Crea una cuenta o inicia sesión

¡Continúa aprendiendo sin ningún costo! Únete y comienza a potenciar tu carrera

Stack de navegación para Pokedex

4/17
Recursos

Aportes 31

Preguntas 9

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad?

Si usan Android y les aparece el header del Tab y el de Stack lo pueden quitar con esa opción en el Tab.Navigator No se si solo a mi me paso por usar ReactNative CLI.

screenOptions={{ headerShown: false }}

Para la versión 6 de react-navigation no es necesario crear un componente de Navigation para cada sección con el fin de cambiar el título. En el mismo Navigation.js se puede pasar como opción headerTitle: “Favoritos”. Ejemplo:

<Tab.Navigator>
            <Tab.Screen 
                name="Favorite"
                component={FavoriteScreen} 
                options={{
                    tabBarLabel:"Favoritos",
                    tabBarIcon: ({ color, size }) => <Icon name="heart" color={color} size={size} />,
                    headerTitle: "Favoritos"
                }}
            />
            <Tab.Screen 
                name="Pokedex"
                component={PokedexScreen}
                options={{
                    tabBarLabel:"",
                    tabBarIcon: () => renderPokeball(),
                    headerTitle: "Pokedexxx"
                }}
            />
            <Tab.Screen 
                name="Account"
                component={AccountScreen}
                options={{
                    tabBarLabel:"Mi cuenta",
                    tabBarIcon: ({ color, size }) => <Icon name="user" color={color} size={size} />,
                    headerTitle: "Mi cuenta"
                }}
            />
        </Tab.Navigator>```

Realmente es una pena que dejen pasar tanto tiempo para actualizar los cursos, como dijo un compañero, en la versión 6 de Tab Navegation, ya no es necesario todo lo que hace en los primeros 7 min!

Les dejo como quedaría el stack para ver los pokemones con la v6.x de Stack Navigation para navegar entre los pokemones que tengas:

Navigation.js

import React from 'react';
import { Image } from "react-native"
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs'
import Icon from "react-native-vector-icons/FontAwesome5";

import FavoriteNavigation from './FavoriteNavigation';
import PokedexNavigation from './PokedexNavigation';
import AccountNavigation from './AccountNavigation';

const Tab = createBottomTabNavigator();

export default function Navigation() {
  return (
    <Tab.Navigator>
      <Tab.Screen
        name="Favoritex"
        component={FavoriteNavigation}
        options={{
          tabBarLabel: "Favoritrix",
          tabBarIcon: ({ color, size }) => (
            <Icon name="heart" color={color} size={size} />),
          headerTitle: "Favoritix",
          headerShown: false
           }}      />

      <Tab.Screen
        name="Pokedexa"
        component={PokedexNavigation}
        options={{
          tabBarLabel: "",
          tabBarIcon: () => renderPokeball(),
          headerShown: false
        }}
      />

      <Tab.Screen
        name="Mi cuenta"
        component={AccountNavigation}
        options={{
          tabBarLabel: "Account",
          tabBarIcon: ({ color, size }) => (
            <Icon name="user" color={color} size={size} />),
          headerTitle: "Account",
          headerShown: false
           }}      />
    </Tab.Navigator>
  );
}

function renderPokeball() {
  return(
    <Image
      source={require('../assets/pokeball.png')}
      style={{ width: 57, height: 57/* top: -1 */ }}
    />
  )
}

PokedexNavigation.js

import React from 'react'
import { createNativeStackNavigator } from "@react-navigation/native-stack";
import PokedexScreen from "../screens/Pokedex";
import PokemonScreen from "../screens/Pokemon";

const Stack = createNativeStackNavigator();

export default function PokedexNavigation() {
  return (
    <Stack.Navigator>
      <Stack.Screen name="Pokedex" component={PokedexScreen}/>
      <Stack.Screen name="Pokemon" component={PokemonScreen}/>
    </Stack.Navigator>
  );
}

Pokemon.js

import React from 'react';
import { View, Text } from 'react-native';


export default function Pokemon() {
  return (
    <View>
      <Text>Estas viendo un POKEMON</Text>
    </View>
  )
}

Cambié algunos nombres para reconocer donde se aplica el cambio

Si estas en Android y quieres que el titulo del header este centrado usa este codigo en options tambien


headerTitleAlign: 'center'

import React from "react";
import { createStackNavigator } from "@react-navigation/stack";
import FavoriteScreen from "../screens/Favorite";

const Stack = createStackNavigator();

export default function FavoriteNavigation() {
  return (
    <Stack.Navigator
      screenOptions={{
        headerShown: false
      }}
    >
      <Stack.Screen
        name="Favorite"
        component={FavoriteScreen}
        options={{
          title: "Favoritos"
        }}
      />
    </Stack.Navigator>
  );
}
import React from "react";
import { createStackNavigator } from "@react-navigation/stack";
import PokedexScreen from "../screens/Pokedex";
import PokemonScreen from "../screens/Pokemon";

const Stack = createStackNavigator();

export default function PokedexNavigation() {
  return (
    <Stack.Navigator
      screenOptions={{
        headerShown: false
      }}
    >
      <Stack.Screen name="Pokemon" component={PokemonScreen} />
      <Stack.Screen name="Pokedex" component={PokedexScreen} />
    </Stack.Navigator>
  );
}
import React from "react";
import { createStackNavigator } from "@react-navigation/stack";
import AccountScreen from "../screens/Account";

const Stack = createStackNavigator();

export default function AccountNavigation() {
  return (
    <Stack.Navigator
      screenOptions={{
        headerShown: false
      }}
    >
      <Stack.Screen
        name="Account"
        component={AccountScreen}
        options={{title: "Mi cuenta" }}
      />
    </Stack.Navigator>
  );
}
import React from "react";
import { View, Text } from "react-native";

export default function Pokemon() {
  return (
    <View>
      <Text>Estamos en un POKEMON</Text>
    </View>
  );
}
import React from "react";
import { Image } from "react-native";
import { createBottomTabNavigator } from "@react-navigation/bottom-tabs";
import Icon from "react-native-vector-icons/FontAwesome5";
import FavoriteNavigation from "./FavoriteNavigation";
import PokedexNavigation from "./PokedexNavigation";
import AccountNavigation from "./AccountNavigation";

const Tab = createBottomTabNavigator();

function renderPokeball() {
  return (
    <Image
      source={require("../assets/pokeball.png")}
      style={{ width: 75, height: 75, top: -15 }}
    />
  );
}

export default function Navigation() {
  return (
    <Tab.Navigator>
      <Tab.Screen
        name="Favorite"
        component={FavoriteNavigation}
        options={{
          tabBarLabel: "Favoritos",
          tabBarIcon: ({ color, size }) => (
            <Icon name="heart" color={color} size={size} />
          ),
        }}
      />

      <Tab.Screen
        name="Pokedex"
        component={PokedexNavigation}
        options={{
          tabBarLabel: "",
          tabBarIcon: () => renderPokeball(),
        }}
      />

      <Tab.Screen
        name="Account"
        component={AccountNavigation}
        options={{
          tabBarLabel: "Mi cuenta",
          tabBarIcon: ({ color, size }) => (
            <Icon name="user" color={color} size={size} />
          ),
        }}
      />
    </Tab.Navigator>
  );
}
Si estas viendo esto en ***2023/2024*** y usas la **version *6* de React Navigation** toma en cuenta lo siguiente: * No necesitas crear los archivos **AccountNavigation.js** ni **FavoriteNavigation.js** (Ya viene el header por default). * Si necesitas crear el archivo **PokedexNavigation.js** ya que usaremos dos "screens". * Oculta los headers de **PkemonScreen** y **PokedexScreen** (ya que el title lo podemos poner directamente en Navigation en el **Tab de Pokedex**. * El código queda de la siguiente manera: * Fragmento de **Navigation.jsx**: * ```js export default function Navigation() { return ( <Tab.Navigator> <Tab.Screen name="Favourites" component={FavouritesScreen} options={{ tabBarLabel: "Favoritos", tabBarIcon: ({color, size}) => ( <Icon name='heart' color={color} size={size} /> ), title: "Favoritos", }} /> <Tab.Screen name="Pokedex" component={PokedexNavigation} options={{ tabBarLabel: "", tabBarIcon: () => renderPokeball(), title: "Pokedex" }} /> <Tab.Screen name="Account" component={AccountScrenn} options={{ tabBarLabel: "Cuenta", tabBarIcon: ({color, size}) => ( <Icon name='circle' color={color} size={size} /> ), title: "Cuenta" }} /> </Tab.Navigator> ); } ```**PokedexNavigation.jsx**: * ```js import React from 'react'; import {createNativeStackNavigator} from '@react-navigation/native-stack'; import PokedexScreen from '../screens/Pokedex'; import PokemonScreen from '../screens/Pokemon'; const Stack = createNativeStackNavigator(); export default function PokedexNavigation() { return ( <Stack.Navigator> <Stack.Screen name="Pokemom" component={PokemonScreen} options={{ headerShown: false }} /> <Stack.Screen name="PokedexChild" component={PokedexScreen} options={{ headerShown: false }} /> </Stack.Navigator> ); } ```

si tienen problemas en que se les repide el Header con esto desactive para que aplique los cambios de createStackNavigator

import { SafeAreaView, View, Text } from "react-native";
import React, { useLayoutEffect } from "react";
import { useNavigation } from "@react-navigation/native";

const Favorite = () => {
  const navigation = useNavigation();

  useLayoutEffect(() => {
    navigation.setOptions({
      headerShown: false,
    });
  }, []);
  return (
    <SafeAreaView>
      <Text>Favorite</Text>
    </SafeAreaView>
  );
};

export default Favorite;

Les dejo una captura de mi Navigation.js

Hola Compañeros, ( al 25/03/22) ya que se ha actualizado navigate a la versión 6, por si llegan a tener alguna dificultad les ire dejando el código que vaya trabajando en el siguiente repositorio:
https://github.com/onedrako/react-native-pokedex-platzi
Éxito en sus desarrollos

Hoy en dia no es necesario crear cada Navigation para cada screen, automaticamente al crear el screen en el archivo Navigation nos coloca el header con el nombre de la pantalla.

Solo necesitamos crear el PokedexNavigation para manejar distintas pantallas que se relacionen con el mismo componente.

En la version 6 el Header del encabezado ya viene por defecto, para poder quitarlo hay que agregar en options headerShown: false en el Navigation.js

par los que no les reconoce el createStackNavigator
hay que instalar esto.

yarn add @react-navigation/stack

Actualicen para la v6.x que hay varios cambios y da problemas generar stack navigation con nuevos componentes

En las versiones más recientes es innecesario combinar Tab con Stack para que tengan en el título en la parte superior. A día de 19/10/2023 Tab Navigation tiene en options el apartado de title en el que se puede añadir el nombre en la parte superior. Por defecto no queda centrado pero con la propiedad headerstyle se le puede centrar.

tengo la version 0.71 de react, el y el stack navigation no fue necesario hacerlo en el android, no estoy seguro como es en ios, esto es porque ya estaba el stack hecho, lo que hice fue agregar esta linea headerTitleAlign: “center”, debajo del tabBarLabel: “Favoritos” para alinear el titulo al centro:

tabBarLabel: "Favoritos",
headerTitleAlign: "center",

Le puedes colorar tu titulo personalizado en el header asi, no es necesario hacer el FavoritesNavigation.js

      <Tab.Screen
        name="Favorites"
        component={FavoritesScreen}
        options={{
          headerTitle: "Favoritos",
          tabBarLabel: "Favoritos",
          tabBarIcon: ({ color, size }) => (
            <AntDesign name="staro" color={color} size={size} />
          ),
        }}
      />

En la version de navigation 6 te ahorras un monton de codigo, no necesitas nada de esto.

en options pones esto

title: "Favoritos",

Estaba teniendo una alerta “[react-native-gesture-handler] Seems like you’re using an old API with gesture components, check out new Gestures system!” y se soluciona bajando la version de esa dependencia “[email protected]

Stack Navigator es una gran herramienta que nos sirve para navegar entre nuestros Screens de una forma sencilla, se maneja por pilas donde cada pantalla se coloca en la parte superior de la pila!

No se si mas adelante vamos a utilizar el stack navigation, pero con una version mas reciente podemos resolver la personalizacion del header con 'headerTitle' desde el componente Tab.Navigation ```js <Tab.Navigator > <Tab.Screen name="Favorite" component={Favorite} options={{ headerTitle:'Favoritos', tabBarLabel: "Favoritos", tabBarIcon: ({ color, size }) => ( <Icon name="heart" color={color} size={size} /> ), }} /> <Tab.Screen name="Pokedex" component={Pokedex} options={{ tabBarLabel: "", headerTitle:'Pokedex', tabBarIcon: () => PokeIcon(), }} /> <Tab.Screen name="Account" component={Account} options={{ tabBarLabel: "Mi Perfil", headerTitle:'Mi Perfil', tabBarIcon: ({ color, size }) => ( <Icon name="user" color={color} size={size} /> ), }} /> </Tab.Navigator> ```
no estoy seguro si mas adelantes utilizaremos el stack navigation.. la version mas reciente me permite personalizar el header con el parametro 'header title' `<Tab.Navigator > <Tab.Screen name="Favorite"` ` component={Favorite} options={{ headerTitle:'Favoritos', tabBarLabel: "Favoritos", tabBarIcon: ({ color, size }) => ( <Icon name="heart" color={color} size={size} /> ), }} /> <Tab.Screen name="Pokedex" component={Pokedex} options={{ tabBarLabel: "", tabBarIcon: () => PokeIcon(), }} /> <Tab.Screen name="Account" component={Account} options={{ tabBarLabel: "Mi Perfil", tabBarIcon: ({ color, size }) => ( <Icon name="user" color={color} size={size} /> ), }} /> </Tab.Navigator>`
Se puede incluir el componente de la imágen directamente dentro del Componente Tab: ```js <Tab.Screen name="Pokedex" component={PokedexScreen} options={{ tabBarLabel: () => <Image source={require("../assets/pokeball.png")} style={{ width: 75, height: 75, top: -15 }} /> }} /> ```\<Tab.Screen        name="Pokedex"        component={PokedexScreen}        options={{          tabBarLabel: () => \<Image                              source={require("../assets/pokeball.png")}                              style={{ width: 75, height: 75, top: -15 }}                            />        }}      />
````tsx Para ocultar el stack duplicado. import React from 'react'; import {createNativeStackNavigator} from '@react-navigation/native-stack'; import Pokedex from '../screens/Pokedex'; const Stack = createNativeStackNavigator(); export default function PokedexNavigation() { return ( <Stack.Navigator> <Stack.Screen name="Pokedex" component={Pokedex} options={{title: '', headerTransparent: true}} /> </Stack.Navigator> ); } ```*import* React *from* 'react';*import* {createNativeStackNavigator} *from* '@react-navigation/native-stack';*import* Pokedex *from* '../screens/Pokedex'; const *Stack* = *createNativeStackNavigator*(); *export* *default* function *PokedexNavigation*() {  *return* (    \<Stack.Navigator>      \<Stack.Screen        *name*="Pokedex"        *component*={Pokedex}        *options*={{title: '', headerTransparent: true}}      />    \</Stack.Navigator>  );} ````

En CLI, si quieren usar el hook de useSafeAreaInsets solo deben primero agregar el SafeAreaProvider a su archivo root

// App.tsx

//... mas imports
import {SafeAreaProvider} from 'react-native-safe-area-context';

function App() {
  return (
    <SafeAreaProvider> {/*aqui*/}
      <NavigationContainer>
        <MyTabs />
      </NavigationContainer>
    </SafeAreaProvider>
  );
}

Y despues en su navigator atributes

// src/navigators/ButtonTabNavigator.tsx

//... mas imports y el createTabNav
import {useSafeAreaInsets} from 'react-native-safe-area-context';

export default function MyTabs() {
  const insets = useSafeAreaInsets(); // inicializa el hook

  return (
    <Tab.Navigator
      sceneContainerStyle={{
        paddingTop: insets.top, /* usa el valor del hook  */
      }}>
	{/* las screens, etc... */}

HACER EL CAMBIO DE NOMBRE EN EL XxxxNavigation para version 6 import React from "react"; import { createNativeStackNavigator } from "@react-navigation/native-stack"; import FavoriteScreen from "../screens/Favorite"; const Stack = createNativeStackNavigator(); export default function FavoriteNavigation() { return ( <Stack.Navigator> <Stack.Screen name="FavoriteY" component={FavoriteScreen} options={{ title: "Favoritos" }} /> </Stack.Navigator> ); }

HACER EL CAMBIO DE NOMBRE EN EL XxxxNavigation para version 6
import React from “react”;
import { createNativeStackNavigator } from “@react-navigation/native-stack”;
import FavoriteScreen from “…/screens/Favorite”;

const Stack = createNativeStackNavigator();

export default function FavoriteNavigation() {
return (
<Stack.Navigator>
<Stack.Screen
name="FavoriteY"
component={FavoriteScreen}
options={{ title: “Favoritos” }}
/>
</Stack.Navigator>
);
}

HACER EL CAMBIO DE NOMBRE EN EL XxxxNavigation para version 6 import React from "react"; import { createNativeStackNavigator } from "@react-navigation/native-stack"; import FavoriteScreen from "../screens/Favorite"; const Stack = createNativeStackNavigator(); export default function FavoriteNavigation() { return ( <Stack.Navigator> <Stack.Screen name="FavoriteY" component={FavoriteScreen} options={{ title: "Favoritos" }} /> </Stack.Navigator> ); }

exelente

People remember install

yarn add @react-navigation/native

or 

npm install @react-navigation/native

Donde comienza la confusión