
Utilisation de `fetch` ou `axios` dans `useEffect`
Apprenez le pattern de base pour récupérer des données d'API en React en utilisant fetch ou axios à l'intérieur du hook useEffect.
Le point d'entrée pour les effets de bord : `useEffect`
Dans les composants fonctionnels React, le hook `useEffect` est l'outil désigné pour gérer les effets de bord (side effects). Les effets de bord sont des opérations qui interagissent avec le monde extérieur au composant lui-même, comme les abonnements, les manipulations directes du DOM, et bien sûr, les requêtes réseau pour communiquer avec des API.
Le moment le plus courant pour effectuer un appel API afin de récupérer des données initiales est juste après le premier rendu du composant (ce qui correspond à l'ancien cycle de vie `componentDidMount` des composants classe). Le hook `useEffect` nous permet de réaliser cela de manière élégante. En fournissant un tableau de dépendances vide (`[]`) comme second argument à `useEffect`, nous indiquons à React que l'effet ne doit s'exécuter qu'une seule fois, après le montage initial du composant.
Nous avons deux principales options pour effectuer ces requêtes HTTP depuis JavaScript : l'API native `fetch` intégrée aux navigateurs modernes, et des bibliothèques tierces populaires comme `axios`.
Récupérer des données avec l'API `fetch` native
L'API `fetch` est une interface moderne et puissante pour effectuer des requêtes réseau. Elle est basée sur les Promesses (Promises), ce qui permet de gérer les opérations asynchrones de manière plus lisible qu'avec les anciens `XMLHttpRequest`.
Voici un exemple typique d'utilisation de `fetch` dans `useEffect` pour récupérer une liste d'éléments depuis une API REST au montage du composant :
import React, { useState, useEffect } from 'react';
function ListeElementsFetch() {
const [items, setItems] = useState([]);
// Idéalement, ajouter aussi des états pour loading et error (vu plus tard)
useEffect(() => {
// Définir une fonction async à l'intérieur de l'effet
const fetchData = async () => {
try {
const response = await fetch('https://api.example.com/items'); // Remplacez par votre URL d'API
// fetch ne rejette pas la promesse pour les erreurs HTTP (4xx, 5xx)
// Il faut vérifier manuellement la propriété 'ok'
if (!response.ok) {
throw new Error(`Erreur HTTP: ${response.status}`);
}
const data = await response.json(); // Parser le corps de la réponse en JSON
setItems(data); // Mettre à jour l'état avec les données reçues
} catch (error) {
console.error("Erreur lors de la récupération des données:", error);
// Ici, on mettrait à jour un état d'erreur
}
};
fetchData(); // Appeler la fonction async
// Le tableau de dépendances vide [] assure que l'effet ne s'exécute qu'au montage
}, []);
return (
Liste des éléments (Fetch)
{items.map(item => (
- {item.name}
// Adaptez selon la structure de vos données
))}
);
}
export default ListeElementsFetch;Points clés à noter :
- L'utilisation de `async/await` à l'intérieur de `useEffect` (en définissant une fonction async interne puis en l'appelant) rend le code plus lisible que l'enchaînement de `.then()`.
- Il est crucial de vérifier `response.ok` car `fetch` considère une réponse comme réussie même si le statut est 404 ou 500 (la promesse n'est rejetée qu'en cas d'échec réseau).
- `response.json()` est elle-même une opération asynchrone qui parse le corps de la réponse.
- Le `try...catch` est essentiel pour attraper les erreurs réseau ou les erreurs levées manuellement (comme lors d'un `!response.ok`).
- Le tableau de dépendances `[]` est fondamental pour éviter que l'appel API ne soit refait à chaque rendu du composant, ce qui créerait une boucle infinie.
Alternative populaire : La bibliothèque `axios`
`axios` est une bibliothèque tierce très populaire pour effectuer des requêtes HTTP. Elle offre plusieurs avantages par rapport à `fetch` natif :
- Elle parse automatiquement les données JSON en réponse.
- Elle rejette la promesse pour les réponses avec des statuts d'erreur HTTP (4xx, 5xx), simplifiant la gestion des erreurs.
- Elle offre une protection contre les failles XSRF intégrée.
- Elle permet d'intercepter les requêtes et les réponses pour ajouter des en-têtes (comme des tokens d'authentification) ou transformer les données globalement.
- Elle fonctionne aussi bien dans le navigateur que dans Node.js.
- Elle facilite l'envoi de données (POST, PUT).
Pour l'utiliser, vous devez d'abord l'installer :
npm install axios
# ou
yarn add axiosVoici le même exemple que précédemment, mais en utilisant `axios` :
import React, { useState, useEffect } from 'react';
import axios from 'axios'; // Importer axios
function ListeElementsAxios() {
const [items, setItems] = useState([]);
// Ajouter loading/error states
useEffect(() => {
const fetchData = async () => {
try {
// Utilisation de axios.get()
const response = await axios.get('https://api.example.com/items');
// axios place les données directement dans response.data
setItems(response.data);
} catch (error) {
// axios rejette la promesse pour les erreurs HTTP
console.error("Erreur lors de la récupération des données (axios):", error);
if (error.response) {
// Erreur venue du serveur (status code hors 2xx)
console.error('Status:', error.response.status);
console.error('Headers:', error.response.headers);
} else if (error.request) {
// Requête envoyée mais pas de réponse reçue
console.error('Request:', error.request);
} else {
// Erreur lors de la configuration de la requête
console.error('Error', error.message);
}
// Mettre à jour l'état d'erreur
}
};
fetchData();
}, []);
return (
Liste des éléments (Axios)
{items.map(item => (
- {item.name}
))}
);
}
export default ListeElementsAxios;Le code est légèrement plus concis, notamment parce qu'il n'est plus nécessaire de vérifier `response.ok` et de parser manuellement le JSON. La gestion des erreurs avec `axios` fournit également plus de détails sur la nature de l'échec.
Points importants et prochaines étapes
Utiliser `fetch` ou `axios` dans `useEffect` avec un tableau de dépendances vide (`[]`) est le pattern fondamental pour charger des données au montage d'un composant. Cependant, cette approche de base présente encore des limitations :
- Gestion des états : Nous n'avons pas encore implémenté de manière explicite les états de chargement (pour afficher un spinner, par exemple) et d'erreur (pour afficher un message à l'utilisateur).
- Dépendances : Si l'URL de l'API dépend d'une prop ou d'une valeur de l'état local (par exemple, un `userId`), cette variable doit être ajoutée au tableau de dépendances de `useEffect`. Cela signifie que l'effet se ré-exécutera (et donc l'appel API sera refait) chaque fois que cette dépendance changera.
- Nettoyage (Cleanup) : Si le composant est démonté pendant que la requête est encore en cours, notre `setItems` (ou la mise à jour d'erreur) tentera de modifier l'état d'un composant qui n'existe plus, provoquant un avertissement React ("Can't perform a React state update on an unmounted component") et potentiellement des fuites mémoire.
Les sections suivantes aborderont spécifiquement la gestion des états de chargement/erreur et l'annulation des requêtes pour rendre nos appels API plus robustes, avant d'explorer des bibliothèques qui automatisent une grande partie de ce travail.