| name | react-native-guide |
| description | Guide de développement React Native avec Expo et navigation. Se déclenche avec "React Native", "Expo", "RN", "react-navigation", "native modules", "bridge", "mobile JavaScript", "Hermes". Also triggers on "React Native app", "Expo setup", "mobile navigation". |
React Native Guide
1. Choix du workflow — critères de décision
| Critère | Expo Managed | Expo Bare | RN CLI pur |
|---|
| Démarrage rapide | ✅ | ✅ | ❌ |
| Accès natif complet | ❌ | ✅ | ✅ |
| EAS Build/Update | ✅ | ✅ | ❌ |
| SDK Expo prêt à l'emploi | ✅ | Partiel | ❌ |
| Maintenance long terme | Facile | Moyenne | Élevée |
Règle : commencer Expo Managed, migrer en Bare uniquement si un module natif custom est indispensable.
npx create-expo-app@latest MyApp --template blank-typescript
cd MyApp && npx expo install expo-router react-native-safe-area-context react-native-screens
2. Navigation — Expo Router (recommandé 2026)
Expo Router v3+ : routing basé sur les fichiers, deep linking automatique, typages TypeScript natifs.
app/
_layout.tsx ← root layout (Stack ou Tabs)
index.tsx ← écran "/"
(tabs)/
_layout.tsx ← Tabs layout
home.tsx ← "/home"
profile.tsx ← "/profile"
[id].tsx ← route dynamique "/123"
import { Stack } from 'expo-router';
export default function RootLayout() {
return <Stack screenOptions={{ headerShown: false }} />;
}
import { router } from 'expo-router';
router.push('/profile');
router.push({ pathname: '/[id]', params: { id: '42' } });
Si React Navigation v6 standalone : préférer createNativeStackNavigator (performances natives) sur createStackNavigator (JS pur).
3. State management — arbre de décision
Données locales à un composant → useState / useReducer
Partage entre quelques écrans → Context + useReducer
Cache serveur / API → TanStack Query v5
État global UI → Zustand
Projet legacy complexe → Redux Toolkit
import { create } from 'zustand';
interface AuthStore { token: string | null; setToken: (t: string) => void; }
export const useAuthStore = create<AuthStore>((set) => ({
token: null,
setToken: (token) => set({ token }),
}));
const { data, isLoading, error } = useQuery({
queryKey: ['user', id],
queryFn: () => api.getUser(id),
staleTime: 60_000,
});
4. UI et styling
- StyleSheet natif : seule option garantissant les perfs sur les deux plateformes.
- NativeWind v4 : Tailwind CSS → StyleSheet, sans overhead runtime.
- Animations : toujours
react-native-reanimated v3 (thread UI) ; éviter Animated de RN core pour tout ce qui dépasse un simple fade.
import Animated, { useSharedValue, withSpring, useAnimatedStyle } from 'react-native-reanimated';
const offset = useSharedValue(0);
const style = useAnimatedStyle(() => ({ transform: [{ translateX: offset.value }] }));
<Animated.View style={[styles.box, style]} />
5. Listes performantes
FlatList cause des janks sur les longues listes. Migrer vers FlashList :
npx expo install @shopify/flash-list
import { FlashList } from '@shopify/flash-list';
<FlashList
data={items}
renderItem={({ item }) => <ItemCard item={item} />}
estimatedItemSize={80} // ← obligatoire, détermine les perfs
keyExtractor={(item) => item.id}
/>
6. Stockage local
| Besoin | Solution |
|---|
| Simple clé-valeur async | @react-native-async-storage/async-storage |
| Haute perf synchrone | react-native-mmkv |
| SQLite relationnel | expo-sqlite (Expo) ou op-sqlite (Bare/RN CLI) |
| Sécurisé (tokens) | expo-secure-store |
import { MMKV } from 'react-native-mmkv';
const storage = new MMKV();
storage.set('token', 'abc123');
const token = storage.getString('token');
7. Modules natifs et nouvelle architecture
React Native 0.74+ : nouvelle architecture activée par défaut (JSI, Fabric, TurboModules).
npx react-native-new-architecture-check
Ordre de priorité pour les modules natifs :
- Expo SDK (caméra, notifications, biométrie, localisation) — zéro config
- Community packages compatibles nouvelle architecture
- Expo Modules API (Swift/Kotlin) pour un module custom
class MyModule : Module() {
override fun definition() = ModuleDefinition {
Name("MyModule")
Function("greet") { name: String -> "Hello, $name!" }
}
}
8. Build et déploiement — EAS
npm install -g eas-cli
eas login && eas build:configure
eas build --platform ios --profile production
eas build --platform android --profile production
eas update --branch production --message "fix: crash liste"
eas submit --platform ios
eas submit --platform android
eas.json — profils types :
{
"build": {
"development": { "developmentClient": true, "distribution": "internal" },
"preview": { "distribution": "internal" },
"production": { "autoIncrement": true }
}
}
9. Performance — checklist
10. Garde-fous et anti-patterns
Ne pas faire :
items.forEach(item => setCount(count + 1));
setCount(items.length);
<FlatList renderItem={({ item }) => <Card item={item} />} />
const renderItem = useCallback(({ item }) => <Card item={item} />, []);
<View style={{ flex: 1, padding: 16 }} />
const styles = StyleSheet.create({ container: { flex: 1, padding: 16 } });
useEffect(() => { subscription = subscribe(); }, []);
( { sub = (); sub.(); }, []);
Pièges courants :
KeyboardAvoidingView : comportement différent iOS (padding) vs Android (height).
- Permissions (caméra, localisation) : demander au runtime, jamais assumer l'accord.
- SafeAreaView : utiliser
react-native-safe-area-context (pas le composant RN core) pour un comportement cohérent sur les notches et Dynamic Island.
- Metro bundler cache corrompu :
npx expo start --clear ou npx react-native start --reset-cache.
- Nouvelle architecture : certains packages populaires restent incompatibles — vérifier
reactnative.directory avant toute installation.
Références rapides