0 XP
?
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 5
code
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