📚 Módulo 10: Mobile - Setup do React Native com Expo, Estrutura e Expo Router
Neste módulo, iniciaremos a jornada de expansão móvel da TecLoja 03. Em vez de usar uma abordagem híbrida baseada em WebView, desenvolveremos um aplicativo completamente nativo utilizando o React Native com Expo (TypeScript). O app consumirá diretamente a API REST construída em NestJS e persistida no banco de dados Neon PostgreSQL nos módulos anteriores.
Estruturaremos o ambiente móvel local com Expo CLI, configuraremos o sistema moderno de navegação baseada em arquivos (Expo Router) e faremos a integração de comunicação com o backend.
🗺️ 1. Arquitetura Nativa Decoplada (NestJS + React Native)
Diferente de um webapp híbrido, o React Native renderiza componentes físicos do sistema operacional Android/iOS em tempo real. Veja o fluxo de dados entre o app e nossa API corporativa:
flowchart TD
%% Styling
classDef reactNative fill:#61DAFB,stroke:#20232A,stroke-width:2px,color:#000;
classDef route fill:#8A2BE2,stroke:#4B0082,stroke-width:2px,color:#fff;
classDef nest fill:#E0234E,stroke:#9F1239,stroke-width:2px,color:#fff;
classDef pg fill:#336791,stroke:#244967,stroke-width:2px,color:#fff;
subgraph Mobile_Client ["📱 Cliente Mobile (React Native + Expo)"]
A[Expo App Core]:::reactNative --> B[Expo Router: Tabs / Stack]:::route
B --> C[Fetch / Axios Request]:::reactNative
end
subgraph Backend_Server ["⚙️ Servidor Backend (NestJS)"]
C <-->|HTTP / JWT Bearer| D[Controllers / Routes]:::nest
D <-->|Prisma ORM ACID| E[PostgreSQL Neon]:::pg
end
⚙️ 2. Inicialização do Projeto Móvel Independente
No modelo multirepo, o aplicativo móvel da TecLoja 03 deve ser desenvolvido em um novo repositório independente do GitHub ou em uma pasta paralela ao frontend web Vite.
Abra o seu terminal na pasta raiz do curso (fora da pasta web) e execute a CLI oficial do Expo para criar o esqueleto TypeScript:
# Criar o app mobile a partir do template recomendado em TypeScript
npx create-expo-app@latest tecloja-mobile --template blank-typescript
Acesse a pasta recém-criada e instale os pacotes necessários para roteamento, estilização nativa e chamadas de API:
cd tecloja-mobile
# Instalar dependências para navegação e consumo HTTP
npx expo install expo-router react-native-safe-area-context react-native-screens expo-linking expo-constants expo-status-bar
npm install axios
Configurando o Expo Router (app/_layout.tsx)
O Expo Router mapeia de forma automatizada os arquivos dentro de uma pasta chamada app em telas físicas do aplicativo (idêntico ao funcionamento de rotas do Next.js).
- Crie a pasta
/app/na raiz do projeto. - Crie o arquivo principal de configuração
/app/_layout.tsx:
import { Stack } from 'expo-router';
import { StatusBar } from 'expo-status-bar';
export default function Layout() {
return (
<>
<StatusBar style="light" backgroundColor="#0f172a" />
<Stack
screenOptions={{
headerStyle: {
backgroundColor: '#0f172a', // Slate 900
},
headerTintColor: '#38bdf8', // Sky 400 (Neon accent)
headerTitleStyle: {
fontWeight: 'bold',
},
contentStyle: {
backgroundColor: '#0f172a',
}
}}
/>
</>
);
}
🧭 3. Criação da Estrutura de Navegação em Abas (Tabs)
Para a navegação interna principal, utilizaremos o padrão de abas inferiores (Bottom Tabs). Crie o arquivo /app/(tabs)/_layout.tsx:
import { Tabs } from 'expo-router';
import { View, Text } from 'react-native';
export default function TabsLayout() {
return (
<Tabs
screenOptions={{
tabBarStyle: {
backgroundColor: '#0f172a',
borderTopColor: '#1e293b',
},
tabBarActiveTintColor: '#38bdf8',
tabBarInactiveTintColor: '#64748b',
headerShown: false,
}}
>
<Tabs.Screen
name="index"
options={{
title: 'Produtos',
// Omitindo ícone para fins didáticos simplificados
}}
/>
<Tabs.Screen
name="carrinho"
options={{
title: 'Carrinho',
}}
/>
<Tabs.Screen
name="perfil"
options={{
title: 'Perfil',
}}
/>
</Tabs>
);
}
E crie a tela inicial de listagem de produtos em /app/(tabs)/index.tsx:
import { StyleSheet, Text, View } from 'react-native';
export default function ProdutosScreen() {
return (
<View style={styles.container}>
<Text style={styles.title}>🛒 TecLoja 03 - Catálogo</Text>
<Text style={styles.subtitle}>Os melhores eletrônicos e produtos de tecnologia do mercado.</Text>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
padding: 24,
backgroundColor: '#0f172a',
},
title: {
fontSize: 24,
fontWeight: 'bold',
color: '#38bdf8',
marginBottom: 8,
},
subtitle: {
fontSize: 16,
color: '#94a3b8',
textAlign: 'center',
},
});
🔗 4. Estabelecendo Conexão com a API NestJS
O emulador Android roda em uma máquina virtual isolada da sua máquina de desenvolvimento. Portanto, se você tentar bater em localhost:3000 (porta do NestJS), o emulador tentará se conectar a si mesmo e falhará.
Para acessar a API local, usaremos o IP especial de loopback 10.0.2.2 no Android, ou o IP físico de rede local do computador caso esteja testando em um celular físico real conectado ao mesmo Wi-Fi.
Criando o Cliente de API em services/api.ts
import axios from 'axios';
import { Platform } from 'react-native';
// IP especial do emulador do Android ou Localhost para iOS/Produção
const API_URL = Platform.OS === 'android'
? 'http://10.0.2.2:3000'
: 'http://localhost:3000';
export const api = axios.create({
baseURL: API_URL,
timeout: 10000,
});
✅ Pré-Requisitos deste Módulo
Antes de iniciar a compilação local, certifique-se de que:
- A API NestJS desenvolvida nos Módulos 02 ao 05 está em execução local no seu computador na porta 3000.
- Você tem o aplicativo auxiliar Expo Go instalado no seu celular de testes físico ou possui o emulador de Android Studio configurado.
🤔 Por que fizemos assim?
- Por que usar Expo em vez de React Native CLI puro? A CLI nativa pura do React Native exige lidar com compilações complexas de códigos em Objective-C/C++ (iOS) e Java/Kotlin (Android) em cada alteração trivial, aumentando a curva de aprendizado. O Expo abstrai toda a infraestrutura complexa sob uma camada de runtime otimizada, acelerando o desenvolvimento e fornecendo o recarregamento rápido instantâneo (Fast Refresh) via Wi-Fi pelo aplicativo Expo Go.
- Por que usar Expo Router baseado em arquivos? Sistemas de navegação tradicionais de React Native (como React Navigation) exigem declaração verbosa de containers de rotas aninhados via código JavaScript. O Expo Router simplifica isso mapeando a própria estrutura física do sistema de arquivos do projeto em rotas, o que facilita o entendimento para alunos habituados com Next.js ou roteamento web tradicional.
🔍 Checkpoint
- Execução do Servidor Expo: Rode
npx expo startno terminal do projeto mobile e confirme se o QR Code e o menu interativo são gerados no console. - Abertura no Aparelho: Escaneie o QR Code usando a câmera do celular (iOS) ou o app Expo Go (Android) e confirme se a tela preta com o texto da TecLoja 03 renderiza corretamente na tela do celular.
⚠️ Erros Comuns
| Erro | Causa | Solução |
|---|---|---|
Network Error ao disparar chamadas HTTP |
O aplicativo tentou bater em localhost:3000 ou a API NestJS está inativa. |
Certifique-se de que o NestJS está de pé na porta 3000 e que você configurou o IP 10.0.2.2 para o emulador de Android ou o IP local físico da rede (ex: 192.168.1.15) no caso de dispositivo físico. |
O Expo Router não encontra as telas ou exibe Route "/" not found |
A pasta /app foi criada com nome incorreto ou o arquivo de inicialização do layout está ausente. |
Mantenha as telas estritamente sob a pasta /app/ na raiz do projeto, respeitando a grafia em letras minúsculas. |
Unable to resolve module ... |
Algum módulo foi importado no código sem que a dependência tenha sido devidamente instalada. | Rode npx expo install nome-do-modulo para garantir a versão compatível com a SDK do Expo em execução. |