Navegação entre telas no React Native com React Navigation V3

react navigation 31 de Mai de 2018
NLW Expert | Evento gratuito de programação na prática | Rocketseat
Desafie-se em uma nova tecnologia criando um projeto completo em 3 aulas no maior evento online e gratuito de programação na prática para todos os níveis da Rocketseat.

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.
NLW Expert | Evento gratuito de programação na prática | Rocketseat
Desafie-se em uma nova tecnologia criando um projeto completo em 3 aulas no maior evento online e gratuito de programação na prática para todos os níveis da Rocketseat.

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;
NLW Expert | Evento gratuito de programação na prática | Rocketseat
Desafie-se em uma nova tecnologia criando um projeto completo em 3 aulas no maior evento online e gratuito de programação na prática para todos os níveis da Rocketseat.

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.

NLW Expert | Evento gratuito de programação na prática | Rocketseat
Desafie-se em uma nova tecnologia criando um projeto completo em 3 aulas no maior evento online e gratuito de programação na prática para todos os níveis da Rocketseat.

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

Marcadores