Pendant des années, le fetching de données en React ressemblait à une succession de useEffect, useState, isLoading et conditions d’erreur. Pour une petite page, cela fonctionne. À mesure que l’application grandit, cette approche devient difficile à maintenir.
C’est là que TanStack Query et React Suspense changent réellement le workflow.
État serveur vs état local
Une donnée récupérée depuis une API n’est pas simplement un état React.
Elle possède :
- une durée de vie ;
- un cache ;
- une date de récupération ;
- un état de fraîcheur ;
- des erreurs ;
- parfois plusieurs consommateurs.
TanStack Query traite précisément ce problème.
const { data, isPending, error } = useQuery({
queryKey: ["users"],
queryFn: fetchUsers,
});
La queryKey identifie la ressource et permet à la bibliothèque de gérer son cache.
Le cache change tout
Imaginons une application avec :
Dashboard
├── Users
├── Orders
└── Statistics
Plusieurs composants peuvent dépendre des mêmes données. Au lieu de déclencher chacun sa propre requête, TanStack Query peut réutiliser le cache et gérer les refetches.
Cela réduit le code et rend les transitions plus prévisibles.
Suspense pour les états de chargement
Avec React Suspense, les composants n’ont plus besoin de transformer chaque chargement en une multitude de conditions.
<Suspense fallback={<UsersSkeleton />}>
<UsersList />
</Suspense>
Le skeleton devient une responsabilité de la frontière d’interface.
Invalidation après mutation
Après une création ou une modification, je préfère invalider explicitement les ressources concernées :
await queryClient.invalidateQueries({
queryKey: ["users"],
});
L’interface peut alors récupérer une version fraîche de la donnée sans que chaque composant connaisse les détails de la requête.
Ce que je garde dans l’état local
Tout ne doit pas être placé dans TanStack Query.
Je réserve généralement l’état local à :
- l’ouverture d’un modal ;
- un onglet sélectionné ;
- une saisie temporaire ;
- une préférence d’interface ;
- un état purement visuel.
Les données provenant du serveur restent dans le cache serveur.
Une architecture plus lisible
React UI
│
├── Local state
│
└── TanStack Query
│
▼
API
│
▼
Backend
Cette séparation permet de comprendre rapidement où vit chaque information.
Les performances
Le cache n’est pas seulement une optimisation. Il évite aussi des requêtes inutiles et permet de revalider les données en arrière-plan.
Je configure notamment selon le besoin :
staleTime;gcTime;- retries ;
- pagination ;
- prefetching.
Il n’existe pas de configuration universelle. Une donnée presque immuable n’a pas la même stratégie qu’un tableau de commandes en temps réel.
Mon principe
Je veux éviter que chaque composant devienne responsable de la totalité du cycle réseau.
TanStack Query gère la donnée serveur. Suspense gère la transition UI. Les composants se concentrent sur l’affichage.
