Navegação entre telas no React Native com React Navigation V3
Quando pensamos em criar uma aplicação, seja ela mobile ou web, nos vem a mente as diversas páginas que a mesma terá. Para tanto é necessário utilizarmos dos recursos de navegação disponíveis em seus respectivos ambientes.
No React Native não é diferente, no entanto não vem de forma nativa. Mas para nos salvar temos o React Navigation que orquestra todo roteamento e navegação de nossa aplicação de forma rápida, direta e muito robusta.
Neste post criaremos uma navegação utilizando o React Navigation que disponibiliza três formas de navegação:
- StackNavigator para navegarmos entre telas por botões dentro da tela.
- TabNavigator para navegarmos através de abas.
- DrawerNavigator para navegarmos através um menu lateral.
Configurando o React Navigation
Vamos começar instalando o plugin do react-navigation no terminal com seguinte comando:
yarn add react-navigation
Instale também o
react-native-gesture-handler
que é responsável por lidar com gestos e toques no React Native:yarn add react-native-gesture-handler
Como o
react-native-gesture-handler
faz alterações na source é necessário você fazer o link:react-native link react-native-gesture-handler
Definindo as páginas
Criaremos duas páginas que serão utilizadas no nosso projeto.
Nossa página Home:
// src/Page1.js import React from 'react'; import { View, Button, Text } from 'react-native'; const Page1 = ({ navigation }) => ( <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}> <Text>Home ;D</Text> <Button title="Ir para About" onPress={() => navigation.navigate('About') } /> </View> ); Page1.navigationOptions = { title: 'Home', } export default Page1;
Nossa página About:
// src/Page2.js import React from 'react'; import { View, Button, Text } from 'react-native'; const Page2 = () => ( <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}> <Text>About</Text> </View> ); Page2.navigationOptions = { title: 'About', } export default Page2;
Configurando o StackNavigator
Para início de conversa vamos com o StackNavigator.
// src/index.js import Page1 from './Page1'; import Page2 from './Page2'; import { createAppContainer, createStackNavigator } from 'react-navigation'; const Routes = createAppContainer( createStackNavigator({ Home: Page1, About: Page2, }) ); export default Routes;
Configurando o index.js
O
index.js
da aplicação ao invés de ler o App.js
lerá o diretório src
, pra isso será feita as seguintes alterações:import { AppRegistry } from "react-native"; import { name as appName } from "./app.json"; import Routes from "./src"; AppRegistry.registerComponent(appName, () => Routes);
Resultado da navegação com StackNavigator
OWW, OMG!!! Só isso???
É meu caro, o trem é simples, não disse? E robusto. Um comentário importante é que utilizamos como parâmetro para o
createStackNavigator
um objeto contendo dois itens e que cada chave desse objeto representa uma rota.Nesse objeto optamos passar o nosso componente stateless direto como
value
da rota, isso se dá porque não definimos nenhuma opção pra ela além do componente. Mas poderíamos muito bem fazer por extenso e passar alguma opção, como segue:const StackNavigator = createStackNavigator({ Home: { screen: Page1, defaultNavigationOptions: { title: 'Home', }, }, });
Podemos também passas diversas opções para a página através da variável estática
defaultNavigationOptions
; como pode ser observado na criação das páginas, que a princípio mudamos apenas o título do Header
, porém há outras opções. AH, e isso vale para os demais navigators.Por fim, observe que utilizamos o
navigation.navigate
para ir para a próxima página. O que é preciso ressaltar aqui é que referenciamos o nome que estava como chave (‘About’) para ir para a página e não o nome do componente Page2.Configurando o TabNavigator
Nessa hora você deve está pensando: “agora o trem vai azedar” e é ai que você se engana meu amigo, pois o que mudará do StackNavigator é a função
createStackNavigator
e só.Sobre isso preciso tecer apenas uma observação, o Android e IOS possuem estilos próprios, e para acompanhar isso o React Navigation separou o TabNavigator em duas funções.
A
createBottomTabNavigator
, que como você deve imaginar, as abas ficam no rodapé e seguem a estilização do IOS. Já a createMaterialTopTabNavigator
as abas ficam no topo e seguem a estilização do Material Design do Android.No exemplo vamos com o
createBottomTabNavigator
:const Routes = createAppContainer( createBottomTabNavigator({ Home: Page1, About: Page2, }) ); export default Routes;
Resultado da navegação do TabNavigator
É sempre bom lembrar que o que muda é o “nome” da função e podemos passar as configurações e estilizações da mesma maneira já mencionada acima.
Você também pode utilizar as fontes de ícones, da uma olhada nesse post que ensinamos a configurar, e deixar bem mais apresentável o seu TabNavigator:
Page1.navigationOptions = { tabBarIcon: <Icon name="Home" size={18} color="#999" /> }
Configurando o DrawerNavigator
Por fim, mas não menos importante, o DrawerNavigator como já esperado alteramos apenas uma função e sua navegação está completa, como não amar isso?
Para o DrawerNavigator funcionar corretamente no Android, precisamos fazer uma alteração a mais no arquivo MainActivity.java como esse guia de instalação mostra: https://kmagiera.github.io/react-native-gesture-handler/docs/getting-started.html#android
const Routes = createAppContainer( createDrawerNavigator({ Home: Page1, About: Page2, }) ); export default Routes;
Resultado da navegação do DrawerNavigator
E por hoje é só…
Bom pessoal, vimos a facilidade que o React Navigation nos trás para criarmos uma navegação completa para nosso App. Existem outras bibliotecas de navegação como é o caso do react-native-navigation que utiliza módulos nativos e proporciona um ganho de performance, mas que é confusa e burocrática a sua utilização. No momento React Navigation atende e muito bem as nossas necessidades.
Ah, existe a possibilidade de juntar isso tudo e fazer a parada ficar ainda mais legal, quem sabe não abordaremos num próximo Post.
O projeto completo no nosso github: https://github.com/Rocketseat/blog-react-navigation