Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Na web, a navegação é baseada em URLs. No mobile, o modelo é diferente: telas são empilhadas umas sobre as outras, como cartas num baralho. Quando o usuário toca num evento, a tela de detalhe entra por cima da lista. O botão “voltar” remove a tela do topo, revelando a anterior.

Esse modelo se chama stack navigation. O React Native não tem navegação embutida — vamos instalar o React Navigation:

$ npx expo install @react-navigation/native @react-navigation/native-stack
$ npx expo install react-native-screens react-native-safe-area-context

O expo install garante que as versões das bibliotecas são compatíveis com a versão do Expo do projeto.

Configurando o stack navigator

Crie src/navigation.tsx:

Arquivo: mobile/src/navigation.tsx
import { createNativeStackNavigator } from "@react-navigation/native-stack";
import EventListScreen from "./EventListScreen";
import EventDetailScreen from "./EventDetailScreen";

export type RootStackParamList = {
  EventList: undefined;
  EventDetail: { eventId: number };
};

const Stack = createNativeStackNavigator<RootStackParamList>();

export default function AppNavigator() {
  return (
    <Stack.Navigator>
      <Stack.Screen
        name="EventList"
        component={EventListScreen}
        options={{ title: "TamoJunto" }}
      />
      <Stack.Screen
        name="EventDetail"
        component={EventDetailScreen}
        options={{ title: "Detalhe do Evento" }}
      />
    </Stack.Navigator>
  );
}

Código 8-4: Stack navigator com duas telas.

O RootStackParamList define os tipos das rotas: EventList não recebe parâmetros, EventDetail recebe um eventId. O TypeScript garante que, ao navegar para EventDetail, o parâmetro eventId é obrigatório — se esquecer, o compilador reclama.

Atualize o App.tsx na raiz do projeto:

Arquivo: mobile/App.tsx
import { NavigationContainer } from "@react-navigation/native";
import AppNavigator from "./src/navigation";

export default function App() {
  return (
    <NavigationContainer>
      <AppNavigator />
    </NavigationContainer>
  );
}

Código 8-5: Ponto de entrada com o container de navegação.

No EventListScreen, cada card precisa ser tocável. Envolva o card com TouchableOpacity e use navigation.navigate para trocar de tela:

import { TouchableOpacity } from "react-native";
import { useNavigation } from "@react-navigation/native";
import { NativeStackNavigationProp } from "@react-navigation/native-stack";
import { RootStackParamList } from "./navigation";

type NavigationProp = NativeStackNavigationProp<RootStackParamList, "EventList">;

export default function EventListScreen() {
  const navigation = useNavigation<NavigationProp>();
  // ... useState, useEffect como antes ...

  return (
    <FlatList
      data={events}
      keyExtractor={(item) => String(item.id)}
      contentContainerStyle={styles.list}
      renderItem={({ item }) => (
        <TouchableOpacity
          onPress={() =>
            navigation.navigate("EventDetail", { eventId: item.id })
          }
        >
          <View style={styles.card}>
            <Text style={styles.title}>{item.title}</Text>
            {/* ... restante do card ... */}
          </View>
        </TouchableOpacity>
      )}
    />
  );
}

Código 8-6: Card tocável que navega para a tela de detalhe.

O TouchableOpacity diminui a opacidade do card quando pressionado, dando feedback visual ao toque — o equivalente ao :hover da web, mas para interação por toque.