Guia Completo para Navegação no React Native com TypeScript

Leonardo Albuquerque - Jun 23 - - Dev Community

Introdução

Neste artigo, vamos explorar como configurar a navegação em um projeto React Native usando TypeScript. Vamos cobrir dois tipos populares de navegadores: o Bottom Tab Navigator e o Stack Navigator. Também abordaremos a estrutura dos tipos de navegação, como definir e usar parâmetros, e a razão de usar undefined em certos casos.

Pré-requisitos

Antes de começarmos, certifique-se de ter o React Native instalado e configurado em seu ambiente de desenvolvimento. Se você não fez isso, siga a documentação oficial para configurar seu ambiente.

Passo 1: Configuração do Projeto

1.1 Criação do Projeto
Crie um novo projeto React Native:

npx react-native init MyNavigationApp
cd MyNavigationApp
Enter fullscreen mode Exit fullscreen mode

1.2 Instalação das Dependências
Instale as dependências necessárias para o React Navigation:

npm install @react-navigation/native @react-navigation/bottom-tabs @react-navigation/stack
npm install react-native-screens react-native-safe-area-context
Enter fullscreen mode Exit fullscreen mode

Instale as definições de tipos para TypeScript:

npm install --save-dev @types/react @types/react-native
npm install --save-dev @types/react-navigation @types/react-navigation-bottom-tabs @types/react-navigation-stack
Enter fullscreen mode Exit fullscreen mode

Passo 2: Definindo Tipos de Navegação

Antes de configurar os navegadores, é essencial definir os tipos de navegação. Isso ajuda a garantir que a navegação seja tipada corretamente, evitando erros comuns.

2.1 Crie um Arquivo de Tipos
Crie um arquivo navigationTypes.ts para definir os tipos de parâmetros de navegação:

// src/navigationTypes.ts

// Define os parâmetros de navegação para o Bottom Tab Navigator
export type BottomTabNavigatorParams = {
  Home: {
    screen: string;
    params: {
      sort: string;
    };
  };
  Settings: undefined; // Esta tela não espera nenhum parâmetro
};

// Define os parâmetros de navegação para o Stack Navigator
export type StackNavigatorParams = {
  Home: undefined; // Esta tela não espera nenhum parâmetro
  Details: {
    itemId: number;
    otherParam: string;
  };
};
Enter fullscreen mode Exit fullscreen mode

Por Que Usar undefined?
Quando uma tela não espera nenhum parâmetro, usamos undefined para indicar isso. Isso ajuda o TypeScript a garantir que você não passe acidentalmente parâmetros para uma tela que não espera nenhum. Por exemplo:

type StackNavigatorParams = {
  Home: undefined; // A tela Home não espera nenhum parâmetro
  Details: {
    itemId: number;
    otherParam: string;
  };
};
Enter fullscreen mode Exit fullscreen mode

Estrutura dos Parâmetros
No exemplo acima, a tela Details espera dois parâmetros: itemId e otherParam. Isso é definido no tipo StackNavigatorParams.

Passo 3: Configuração do React Navigation

3.1 Configuração Inicial
Configure a inicialização do React Navigation no arquivo index.js:

import 'react-native-gesture-handler';
import { AppRegistry } from 'react-native';
import App from './App';
import { name as appName } from './app.json';

AppRegistry.registerComponent(appName, () => App);

3.2 Configuração do App.tsx com Bottom Tab Navigator

// App.tsx
import * as React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import HomeScreen from './src/screens/HomeScreen';
import SettingsScreen from './src/screens/SettingsScreen';

// Importa os tipos definidos no arquivo de tipos
import { BottomTabNavigatorParams } from './src/navigationTypes';

// Criação do Bottom Tab Navigator
const Tab = createBottomTabNavigator<BottomTabNavigatorParams>();

// Componente principal com a navegação
export default function App() {
  return (
    <NavigationContainer>
      <Tab.Navigator>
        <Tab.Screen name="Home" component={HomeScreen} />
        <Tab.Screen name="Settings" component={SettingsScreen} />
      </Tab.Navigator>
    </NavigationContainer>
  );
}
Enter fullscreen mode Exit fullscreen mode

3.3 Configuração do App.tsx com Stack Navigator

// App.tsx
import * as React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import HomeScreen from './src/screens/HomeScreen';
import DetailsScreen from './src/screens/DetailsScreen';

// Importa os tipos definidos no arquivo de tipos
import { StackNavigatorParams } from './src/navigationTypes';

// Criação do Stack Navigator
const Stack = createStackNavigator<StackNavigatorParams>();

// Componente principal com a navegação
export default function App() {
  return (
    <NavigationContainer>
      <Stack.Navigator>
        <Stack.Screen name="Home" component={HomeScreen} />
        <Stack.Screen name="Details" component={DetailsScreen} />
      </Stack.Navigator>
    </NavigationContainer>
  );
}
Enter fullscreen mode Exit fullscreen mode

Passo 4: Criando as Telas

4.1 Tela Home para Bottom Tab Navigator

// src/screens/HomeScreen.tsx
import * as React from 'react';
import { View, Text, Button } from 'react-native';
import { useNavigation } from '@react-navigation/native';
import { BottomTabNavigationProp } from '@react-navigation/bottom-tabs';
import { BottomTabNavigatorParams } from '../navigationTypes';

type HomeScreenNavigationProp = BottomTabNavigationProp<BottomTabNavigatorParams, 'Home'>;

const HomeScreen: React.FC = () => {
  const navigation = useNavigation<HomeScreenNavigationProp>();

  const navigateToFeed = () => {
    navigation.navigate('Home', {
      screen: 'Feed',
      params: { sort: 'latest' },
    });
  };

  return (
    <View>
      <Text>Home Screen</Text>
      <Button title="Go to Feed" onPress={navigateToFeed} />
    </View>
  );
};

export default HomeScreen;
Enter fullscreen mode Exit fullscreen mode

4.2 Tela Settings para Bottom Tab Navigator

// src/screens/SettingsScreen.tsx
import * as React from 'react';
import { View, Text } from 'react-native';

const SettingsScreen: React.FC = () => {
  return (
    <View>
      <Text>Settings Screen</Text>
    </View>
  );
};

export default SettingsScreen;
Enter fullscreen mode Exit fullscreen mode

4.3 Tela Home para Stack Navigator

// src/screens/HomeScreen.tsx
import * as React from 'react';
import { View, Text, Button } from 'react-native';
import { useNavigation } from '@react-navigation/native';
import { StackNavigationProp } from '@react-navigation/stack';
import { StackNavigatorParams } from '../navigationTypes';

type HomeScreenNavigationProp = StackNavigationProp<StackNavigatorParams, 'Home'>;

const HomeScreen: React.FC = () => {
  const navigation = useNavigation<HomeScreenNavigationProp>();

  const navigateToDetails = () => {
    navigation.navigate('Details', {
      itemId: 42,
      otherParam: 'anything you want here',
    });
  };

  return (
    <View>
      <Text>Home Screen</Text>
      <Button title="Go to Details" onPress={navigateToDetails} />
    </View>
  );
};

export default HomeScreen;
Enter fullscreen mode Exit fullscreen mode

4.4 Tela Details para Stack Navigator

// src/screens/DetailsScreen.tsx
import * as React from 'react';
import { View, Text } from 'react-native';
import { useRoute, RouteProp } from '@react-navigation/native';
import { StackNavigatorParams } from '../navigationTypes';

type DetailsScreenRouteProp = RouteProp<StackNavigatorParams, 'Details'>;

const DetailsScreen: React.FC = () => {
  const route = useRoute<DetailsScreenRouteProp>();

  // Acessando parâmetros
  const { itemId, otherParam } = route.params;

  return (
    <View>
      <Text>Details Screen</Text>
      <Text>itemId: {itemId}</Text>
      <Text>otherParam: {otherParam}</Text>
    </View>
  );
};

export default DetailsScreen;
Enter fullscreen mode Exit fullscreen mode

Passo 5: Entendendo e Usando Parâmetros

Como Definir Parâmetros
No exemplo acima, a tela Details espera dois parâmetros: itemId e otherParam. Esses parâmetros são definidos no tipo StackNavigatorParams.

// src/navigationTypes.ts
export type StackNavigatorParams = {
  Home: undefined; // Esta tela não espera nenhum parâmetro
  Details: {
    itemId: number;
    otherParam: string;
  };
};
Enter fullscreen mode Exit fullscreen mode

Como Navegar com Parâmetros
Para navegar para a tela Details com os parâmetros itemId e otherParam, usamos o navigate como mostrado no exemplo da HomeScreen:

const navigateToDetails = () => {
  navigation.navigate('Details', {
    itemId: 42,
    otherParam: 'anything you want here',
  });
};
Enter fullscreen mode Exit fullscreen mode

Como Receber Parâmetros
Para acessar os parâmetros dentro de uma tela, usamos o hook useRoute do React Navigation:

import { useRoute, RouteProp } from '@react-navigation/native';

type DetailsScreenRouteProp = RouteProp<StackNavigatorParams, 'Details'>;

const DetailsScreen: React.FC = () => {
  const route = useRoute<DetailsScreenRouteProp>();

  // Acessando parâmetros
  const { itemId, otherParam } = route.params;

  return (
    <View>
      <Text>Details Screen</Text>
      <Text>itemId: {itemId}</Text>
      <Text>otherParam: {otherParam}</Text>
    </View>
  );
};

export default DetailsScreen;
Enter fullscreen mode Exit fullscreen mode

Conclusão
Este guia detalhado mostrou como configurar tanto o Bottom Tab Navigator quanto o Stack Navigator com TypeScript em um projeto React Native. Começamos definindo os tipos de navegação para garantir uma tipagem segura ao longo do projeto. Em seguida, configuramos os navegadores e criamos telas simples para demonstração. Discutimos também a estrutura dos tipos de parâmetros de navegação e por que usamos undefined para indicar telas que não esperam parâmetros.

Implementar navegação em um aplicativo é um passo fundamental para proporcionar uma experiência de usuário fluida e intuitiva. Com o React Navigation e TypeScript, você pode construir aplicativos robustos e com menos erros de tipagem, melhorando a qualidade e a manutenibilidade do código.

Espero que este guia tenha sido útil e que você agora se sinta confortável para começar a implementar navegação em seus próprios projetos React Native com TypeScript!

. . . .