Intermédiaire50 min35 XP
Objectifs de cette leçon
- Persister des données avec AsyncStorage
- Gérer les préférences utilisateur
- Comprendre les options de stockage mobile
Stockage local en React Native 💾
Les apps mobiles doivent souvent sauvegarder des données même hors-ligne. Heureusement, React Native a plusieurs solutions de stockage !
1. AsyncStorage — le stockage clé-valeur 🔑
' AsyncStorage = comme un petit tiroir où on range des trucs ' On donne une CLÉ et une VALEUR (du texte uniquement) ' Les données persistent même si on ferme l'app ! ' Avantages : simple, installation rapide ' Inconvénients : lent, pas de requêtes complexes ' À utiliser pour : préférences, token, petits réglages
import AsyncStorage from "@react-native-async-storage/async-storage"; // Sauvegarder async function sauvegarderPrefs() { try { const preferences = { theme: "sombre", notifications: true, langue: "fr", }; await AsyncStorage.setItem("preferences", JSON.stringify(preferences)); } catch (err) { console.error("Erreur de sauvegarde :", err); } } // Lire async function chargerPrefs() { try { const json = await AsyncStorage.getItem("preferences"); return json ? JSON.parse(json) : null; } catch (err) { console.error("Erreur de lecture :", err); return null; } } // Supprimer async function supprimerPrefs() { try { await AsyncStorage.removeItem("preferences"); } catch (err) { console.error("Erreur de suppression :", err); } } ``' --- ## 2. MMKV — le remplacement ultra-rapide ⚡ ```text ' MMKV = version améliorée d'AsyncStorage ' Développé par Tencent (WeChat) ' 30× plus rapide qu'AsyncStorage ! ' Pourquoi MMKV est plus rapide ? ' • Écrit directement sur le disque (pas de bridge JS) ' • Pas besoin de JSON.stringify/parse ' • Synchronisé (pas async) → pas d'attente ``' ```tsx import { MMKV } from "react-native-mmkv"; // Création du stockage const stockage = new MMKV({ id: "mon-app-stockage", encryptionKey: "ma-cle-secrete", // Optionnel : chiffrement ! }); // Utilisation (sans async !) stockage.set("theme", "sombre"); stockage.set("compteur", 42); stockage.set("estConnecte", true); const theme = stockage.getString("theme"); const compteur = stockage.getNumber("compteur"); const connecte = stockage.getBoolean("estConnecte"); // Réactif : écouter les changements const useUtilisateur = () => { return stockage.getString("nom_utilisateur") || "Invité"; }; ``' --- ## 3. SQLite — pour les données structurées 🗃️ ```text ' SQLite = une vraie base de données relationnelle ' Comme MySQL ou PostgreSQL, mais dans le téléphone ! ' Tables, requêtes SQL, index, transactions... ' Parfait pour : notes, messages, données complexes ' À utiliser quand : ' • Beaucoup de données (1000+ enregistrements) ' • Besoin de rechercher/trier/filtrer ' • Relations entre les données ``' ```tsx import * as SQLite from "expo-sqlite"; // 1. Ouvrir la base const db = await SQLite.openDatabaseAsync("notes.db"); // 2. Créer une table await db.execAsync(` CREATE TABLE IF NOT EXISTS notes ( id INTEGER PRIMARY KEY AUTOINCREMENT, titre TEXT NOT NULL, contenu TEXT, date_creation TEXT DEFAULT CURRENT_TIMESTAMP, favori INTEGER DEFAULT 0 ); `); // 3. Insérer une note async function ajouterNote(titre: string, contenu: string) { const resultat = await db.runAsync( "INSERT INTO notes (titre, contenu) VALUES (?, ?)", titre, contenu, ); return resultat.lastInsertRowId; } // 4. Lire toutes les notes async function getNotes() { return db.getAllAsync( "SELECT * FROM notes ORDER BY date_creation DESC" ); } // 5. Rechercher des notes async function rechercherNotes(texte: string) { return db.getAllAsync( "SELECT * FROM notes WHERE titre LIKE ?", `%${texte}%`, ); } // 6. Mettre à jour async function toggleFavori(id: number) { await db.runAsync( "UPDATE notes SET favori = NOT favori WHERE id = ?", id, ); } // 7. Supprimer async function supprimerNote(id: number) { await db.runAsync("DELETE FROM notes WHERE id = ?", id); } ``' --- ## 4. Stockage sécurisé des données sensibles 🔒 ```tsx // Ne JAMAIS stocker des tokens/mots de passe dans AsyncStorage ! // Utiliser Expo SecureStore ou react-native-keychain import * as SecureStore from "expo-secure-store"; // Ces données sont chiffrées par le système (Keychain iOS / Keystore Android) async function stockerSecurise() { await SecureStore.setItemAsync("jwt_token", "mon-token-secret"); await SecureStore.setItemAsync("email", "user@exemple.com"); } async function lireSecurise() { const token = await SecureStore.getItemAsync("jwt_token"); const email = await SecureStore.getItemAsync("email"); return { token, email }; } ``' --- ## Schéma récapitulatif 🧭 ```mermaid flowchart TD A["💾 Stockage local"] --> B["Clé-Valeur<br/>Simple"] A --> C["Base de données<br/>Relationnelle"] A --> D["Sécurisé<br/>Chiffré"] B --> E["AsyncStorage<br/>⚠️ Lent, simple"] B --> F["MMKV ⚡<br/>30× plus rapide"] C --> G["expo-sqlite<br/>Requêtes SQL"] C --> H["WatermelonDB<br/>🚀 Ultra rapide"] D --> I["SecureStore<br/>iOS Keychain"] ``' --- ## Exercices pour toi 🎯 1. **AsyncStorage** : crée une app de "liste de courses" avec ajout, suppression et persistance 2. **MMKV** : remplace AsyncStorage par MMKV et mesure la différence de vitesse (sans JSON.stringify) 3. **SQLite** : crée une app de notes avec recherche, tri par date et marquage favori
Création des variables pas à pas
Prêt à explorer la mémoire
Appuie sur Play pour voir les variables se créer une par une
0/5
Visualisation d'exécution
ligne 5code
1import AsyncStorage from '@react-native-async-storage/async-storage';
2
3async function sauvegarderTheme(theme: string) {
4 try {
5 await AsyncStorage.setItem('theme', theme);
6 console.log('Thème sauvegardé :', theme);
7 } catch (e) {
8 console.error('Erreur de sauvegarde', e);
9 }
10}
11
12async function chargerTheme() {
13 try {
14 const theme = await AsyncStorage.getItem('theme');
15 return theme ?? 'light'; // valeur par défaut
16 } catch (e) {
17 return 'light';
18 }
19}
Variables
AsyncStorage.setItem('theme', …)=sauvegarde dans le téléphone
AsyncStorage.getItem('theme')=retourne 'dark' ou null
💾 AsyncStorage — Simulateur
📦 Stockage
{}📋 Journal