Project Creation
```bash
# Install Expo CLI
npm install -g expo-cli
# Create new project
npx create-expo-app my-app
cd my-app
# Start development server
npx expo start
```
Folder Structure
```
my-app/
βββ app/ # Expo Router pages
β βββ (tabs)/ # Tab navigation
β β βββ index.tsx # Home tab
β β βββ explore.tsx # Explore tab
β β βββ _layout.tsx # Tab layout
β βββ _layout.tsx # Root layout
β βββ +not-found.tsx # 404 page
βββ components/ # Reusable components
βββ hooks/ # Custom hooks
βββ constants/ # Constants
βββ assets/ # Images, fonts, etc.
βββ app.json # Expo configuration
βββ package.json
```
Navigation Patterns
```typescript
// app/_layout.tsx - Stack navigation
import { Stack } from 'expo-router';
export default function RootLayout() {
return (
);
}
```
```typescript
// app/(tabs)/_layout.tsx - Tab navigation
import { Tabs } from 'expo-router';
import { Ionicons } from '@expo/vector-icons';
export default function TabLayout() {
return (
name="index"
options={{
title: 'Home',
tabBarIcon: ({ color }) => ,
}}
/>
name="profile"
options={{
title: 'Profile',
tabBarIcon: ({ color }) => ,
}}
/>
);
}
```
Styling Patterns
```typescript
// Basic StyleSheet
import { StyleSheet, View, Text } from 'react-native';
export function MyComponent() {
return (
Hello
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
padding: 16,
backgroundColor: '#fff',
},
title: {
fontSize: 24,
fontWeight: 'bold',
},
});
```
```typescript
// NativeWind (Tailwind for RN) - Recommended
import { View, Text } from 'react-native';
export function MyComponent() {
return (
Hello
);
}
```
API Integration
```typescript
// hooks/useApi.ts
import { useState, useEffect } from 'react';
export function useApi(endpoint: string) {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
const fetchData = async () => {
try {
const response = await fetch(${process.env.EXPO_PUBLIC_API_URL}${endpoint});
if (!response.ok) throw new Error('API Error');
const json = await response.json();
setData(json);
} catch (e) {
setError(e as Error);
} finally {
setLoading(false);
}
};
fetchData();
}, [endpoint]);
return { data, loading, error };
}
```
Authentication Pattern
```typescript
// context/AuthContext.tsx
import { createContext, useContext, useState, useEffect } from 'react';
import * as SecureStore from 'expo-secure-store';
interface AuthContextType {
user: User | null;
signIn: (email: string, password: string) => Promise;
signOut: () => Promise;
}
const AuthContext = createContext(null);
export function AuthProvider({ children }: { children: React.ReactNode }) {
const [user, setUser] = useState(null);
useEffect(() => {
// Check for stored token on app start
const loadToken = async () => {
const token = await SecureStore.getItemAsync('authToken');
if (token) {
// Load user info with token
}
};
loadToken();
}, []);
const signIn = async (email: string, password: string) => {
const response = await fetch('/api/auth/login', {
method: 'POST',
body: JSON.stringify({ email, password }),
});
const { token, user } = await response.json();
await SecureStore.setItemAsync('authToken', token);
setUser(user);
};
const signOut = async () => {
await SecureStore.deleteItemAsync('authToken');
setUser(null);
};
return (
{children}
);
}
export const useAuth = () => useContext(AuthContext)!;
```
---