0 XP
?
Intermédiaire55 min40 XP

Objectifs de cette leçon

  • Effectuer des requêtes API avec fetch/axios
  • Gérer les erreurs réseau
  • Afficher des données depuis une API

Communication réseau et API 🌐

Une app mobile sans réseau, c'est comme un téléphone sans forfait ! React Native permet d'appeler des API, gérer l'authentification et même du temps réel.


1. fetch et axios — les appels API 🔌

' fetch = intégré à JavaScript (pas besoin d'installer)
' axios = bibliothèque externe (plus de fonctionnalités)

' HTTP (GET, POST, PUT, DELETE) = les verbes de la communication
'   GET    → lire des données
'   POST   → créer des données
'   PUT    → modifier des données
'   DELETE → supprimer des données

tsx // Avec fetch (natif) interface Article { id: number; titre: string; contenu: string; auteur: string; }

async function chargerArticles(): Promise<Article[]> { const reponse = await fetch("https://api.exemple.com/articles", { method: "GET", headers: { "Content-Type": "application/json", Authorization: "Bearer token123", }, });

if (!reponse.ok) { throw new Error(Erreur HTTP : ${reponse.status}); }

return reponse.json(); }

// Avec axios (plus concis) import axios from "axios";

const api = axios.create({ baseURL: "https://api.exemple.com", timeout: 10000, // 10 secondes max headers: { "Content-Type": "application/json" }, });

// Intercepteur : ajoute le token à TOUTES les requêtes api.interceptors.request.use((config) => { const token = "mon-jwt-token"; config.headers.Authorization = Bearer ${token}; return config; });

// Utilisation const { data } = await api.get<Article[]>("/articles"); const nouveau = await api.post("/articles", { titre: "Mon article" }); ``'


2. Gestion des erreurs et loading ⚠️

import { useState } from "react";
import { View, Text, TouchableOpacity, ActivityIndicator, StyleSheet } from "react-native";

function ChargementDonnees() {
  const [donnees, setDonnees] = useState<Article[]>([]);
  const [loading, setLoading] = useState(false);
  const [erreur, setErreur] = useState<string | null>(null);

  const charger = async () => {
    setLoading(true);
    setErreur(null);

    try {
      const reponse = await fetch("https://api.exemple.com/articles");

      if (!reponse.ok) {
        if (reponse.status === 401) throw new Error("Non autorisé");
        if (reponse.status === 404) throw new Error("Pas trouvé");
        throw new Error("Erreur serveur");
      }

      const data = await reponse.json();
      setDonnees(data);
    } catch (err) {
      if (err instanceof TypeError) {
        setErreur("Pas de connexion internet");
      } else {
        setErreur(err.message);
      }
    } finally {
      setLoading(false);
    }
  };

  return (
    <View style={styles.container}>
      <TouchableOpacity onPress={charger} disabled={loading}>
        <Text>{loading ? "Chargement..." : "Charger"}</Text>
      </TouchableOpacity>

      {loading && <ActivityIndicator size="large" color="#6200ee" />}

      {erreur && (
        <View style={styles.erreur}>
          <Text style={styles.erreurTexte}>❌ {erreur}</Text>
          <TouchableOpacity onPress={charger}>
            <Text style={styles.retry}>Réessayer</Text>
          </TouchableOpacity>
        </View>
      )}

      {donnees.map((article) => (
        <Text key={article.id}>{article.titre}</Text>
      ))}
    </View>
  );
}
``'

---

## 3. Authentification JWT 🔐

```text
' JWT (JSON Web Token) = un "pass" numérique
' 1. L'utilisateur se connecte (email + mot de passe)
' 2. Le serveur vérifie et renvoie un JWT
' 3. L'app stocke le JWT (dans un endroit sécurisé)
' 4. Chaque requête inclut le JWT dans l'en-tête
' 5. Le serveur vérifie le JWT avant de répondre
``'

tsx
// Stockage sécurisé du token
import * as SecureStore from "expo-secure-store";

const TOKEN_KEY = "auth_token";

export async function sauvegarderToken(token: string) {
  await SecureStore.setItemAsync(TOKEN_KEY, token);
}

export async function getToken(): Promise<string | null> {
  return SecureStore.getItemAsync(TOKEN_KEY);
}

export async function supprimerToken() {
  await SecureStore.deleteItemAsync(TOKEN_KEY);
}

// Connexion
async function connexion(email: string, motDePasse: string) {
  const reponse = await fetch("https://api.exemple.com/login", {
    method: "POST",
    body: JSON.stringify({ email, motDePasse }),
  });

  if (!reponse.ok) throw new Error("Email ou mot de passe incorrect");

  const { token } = await reponse.json();
  await sauvegarderToken(token);
}
``'

---

## 4. WebSockets — temps réel ⚡

```tsx
import { useEffect, useState } from "react";
import { Text, View } from "react-native";

function ChatTempsReel() {
  const [messages, setMessages] = useState<string[]>([]);
  const [socket, setSocket] = useState<WebSocket | null>(null);

  useEffect(() => {
    // Connexion WebSocket
    const ws = new WebSocket("wss://chat.exemple.com");

    ws.onopen = () => console.log("Connecté au chat");
    ws.onmessage = (event) => {
      setMessages((prev) => [...prev, event.data]);
    };
    ws.onclose = () => console.log("Déconnecté");
    ws.onerror = (err) => console.error("Erreur WS", err);

    setSocket(ws);

    // Nettoyage
    return () => ws.close();
  }, []);

  const envoyerMessage = (texte: string) => {
    socket?.send(JSON.stringify({ type: "message", texte }));
  };

  return (
    <View>
      {messages.map((msg, i) => (
        <Text key={i}>{msg}</Text>
      ))}
    </View>
  );
}
``'

---

## 5. Bonnes pratiques ✅

```text
' 1. TOUJOURS gérer les erreurs (try/catch)
' 2. Afficher un indicateur de chargement
' 3. Timeout sur chaque requête (max 10-15 sec)
' 4. Retry automatique si échec (3 tentatives max)
' 5. Cache les réponses pour éviter de recharger
' 6. Stocker les tokens dans un endroit SÉCURISÉ
' 7. Ne JAMAIS mettre les clés API en dur dans le code
``'

---

## Exercices pour toi 🎯

1. **GET + liste** : utilise l'API JSONPlaceholder (`/posts`) pour afficher une liste de posts avec FlatList, loading et gestion d'erreur
2. **POST + formulaire** : crée un formulaire d'inscription qui envoie email + password à une API et gère la réponse (succès/erreur)
3. **JWT complet** : implémente login → stockage du token → requête authentifiée → déconnexion

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 14
code
1import { useState, useEffect } from 'react';
2import { View, Text, ActivityIndicator } from 'react-native';
3
4export default function ListeArticles() {
5 const [donnees, setDonnees] = useState(null);
6 const [loading, setLoading] = useState(true);
7 const [erreur, setErreur] = useState(null);
8
9 useEffect(() => {
10 fetch('https://api.exemple.com/articles')
11 .then(res => res.json())
12 .then(setDonnees)
13 .catch(setErreur)
14 .finally(() => setLoading(false));
15 }, []);
16
17 if (loading) return <ActivityIndicator />;
18 if (erreur) return <Text>Erreur : {erreur}</Text>;
19 return <Text>{donnees.length} articles</Text>;
20}
Variables
donnees=null (pas encore chargé)
loading=true (chargement en cours)
erreur=null (aucune erreur)

🌐 Cycle de vie d'un appel API

⏸ Repos
⏳ Chargement
✅ Succès
❌ Erreur
Clique sur “Lancer la requête” pour simuler un appel API

⚡ Simulateur — Communication réseau

Étape 1/8
📝 Pseudo-code
1// Communication réseau dans React Native
2import { useState, useEffect } from 'react';
3
4function UserList() {
5 const [users, setUsers] = useState([]); # ⬅ état
6 const [loading, setLoading] = useState(true);
7
8 useEffect(() => { # ⬅ au montage
9 fetch('https://api.exemple.com/users') # ⬅ requête GET
10 .then(res => res.json()) # ⬅ parser JSON
11 .then(data => {
12 setUsers(data); # ⬅ stocker
13 setLoading(false);
14 })
15 .catch(err => console.error(err)); # ⬅ erreur
16 }, []);
17
18 if (loading) return <Text>Chargement...</Text>; # ⬅ loading
19 return <Text>{users.length} utilisateurs</Text>; # ⬅ résultat
🌐 Communication réseau
💡 Cycle API
MontageuseEffectfetch()setStateRe-rendu

React Native utilise fetch() comme sur le web pour communiquer avec des API.