Guide Apollo Client 4.x
Apollo Client est une bibliothèque complète de gestion d'état pour JavaScript qui vous permet de gérer à la fois les données locales et distantes avec GraphQL. La version 4.x apporte un meilleur caching, un support TypeScript amélioré et la compatibilité avec React 19.
Guides d'intégration
Choisissez le guide d'intégration qui correspond à votre configuration applicative :
- Applications côté client - Pour les applications React côté client sans SSR (Vite, Create React App, etc.)
- Next.js App Router - Pour les applications Next.js utilisant l'App Router avec React Server Components
- React Router Framework Mode - Pour les applications React Router 7 avec SSR en streaming
- TanStack Start - Pour les applications TanStack Start avec routage moderne
Chaque guide comprend les étapes d'installation, la configuration et les patterns spécifiques au framework optimisés pour cet environnement.
Référence rapide
Requête de base
import { gql } from "@apollo/client";
import { useQuery } from "@apollo/client/react";
const GET_USER = gql`
query GetUser($id: ID!) {
user(id: $id) {
id
name
}
}
`;
function UserProfile({ userId }: { userId: string }) {
const { loading, error, data, dataState } = useQuery(GET_USER, {
variables: { id: userId },
});
if (loading) return <p>Loading...</p>;
if (error) return <p>Error: {error.message}</p>;
// TypeScript note: for stricter type narrowing, you can also check `dataState === "complete"` before accessing data
return <div>{data?.user.name}</div>;
}
Mutation de base
import { gql } from "@apollo/client";
import { useMutation } from "@apollo/client/react";
const CREATE_USER = gql`
mutation CreateUser($input: CreateUserInput!) {
createUser(input: $input) {
id
name
}
}
`;
function CreateUserForm() {
const [createUser, { loading, error }] = useMutation(CREATE_USER);
const handleSubmit = async (name: string) => {
await createUser({ variables: { input: { name } } });
};
return <button onClick={() => handleSubmit("John")}>Create User</button>;
}
Requête avec Suspense
import { Suspense } from "react";
import { useSuspenseQuery } from "@apollo/client/react";
function UserProfile({ userId }: { userId: string }) {
const { data } = useSuspenseQuery(GET_USER, {
variables: { id: userId },
});
return <div>{data.user.name}</div>;
}
function App() {
return (
<Suspense fallback={<p>Loading user...</p>}>
<UserProfile userId="1" />
</Suspense>
);
}
Fichiers de référence
Documentation détaillée pour des sujets spécifiques :
- Génération de code TypeScript - Configuration de GraphQL Code Generator pour les opérations type-safe
- Requêtes - useQuery, useLazyQuery, polling, refetching
- Hooks Suspense - useSuspenseQuery, useBackgroundQuery, useReadQuery, useLoadableQuery
- Mutations - useMutation, UI optimiste, mises à jour du cache
- Fragments - Fragment colocation, useFragment, useSuspenseFragment, data masking
- Caching - InMemoryCache, typePolicies, manipulation du cache
- Gestion d'état - Variables réactives, état local
- Gestion des erreurs - Stratégies d'erreur, error links, retries
- Dépannage - Problèmes courants et solutions
Règles clés
Bonnes pratiques pour les requêtes
- Chaque page devrait généralement n'avoir qu'une seule requête, composée de fragments colocalisés. Utilisez
useFragmentouuseSuspenseFragmentdans tous les composants non-page. Utilisez@deferpour permettre aux champs lents sous la ligne de flottaison de s'afficher plus tard et éviter de bloquer le chargement de la page. - Les fragments sont pour la colocation, pas pour la réutilisation. Chaque fragment doit décrire exactement les besoins en données d'un composant spécifique, et ne doit pas être partagé entre composants pour des champs communs. Voir la référence Fragments pour les détails sur la colocation des fragments et le data masking.
- Traitez toujours les états
loadingeterrordans l'interface utilisateur quand vous utilisez des hooks non-suspenseful (useQuery,useLazyQuery). Quand vous utilisez des hooks Suspense (useSuspenseQuery,useBackgroundQuery), React gère cela via les limites<Suspense>et les error boundaries. - Utilisez
fetchPolicypour contrôler le comportement du cache par requête - Utilisez le serveur de types TypeScript pour consulter la documentation des fonctions et options (Apollo Client a des docblocks étendus)
Bonnes pratiques pour les mutations
- Si le schéma le permet, les valeurs renvoyées par la mutation doivent retourner tout ce qui est nécessaire pour mettre à jour le cache. Ni les mises à jour manuelles ni le refetching ne devraient être nécessaires.
- Si la réponse de la mutation est insuffisante, pesez soigneusement la manipulation manuelle du cache par rapport au refetching. Les mises à jour manuelles risquent de manquer la logique serveur. Envisagez les mises à jour optimistes avec un refetch granulaire si nécessaire.
- Gérez les erreurs avec élégance dans l'interface utilisateur
- Utilisez
refetchQueriesavec parcimonie (préférez laisser le cache se mettre à jour automatiquement)
Bonnes pratiques pour le caching
- Configurez
keyFieldspour les types sans champid - Désactivez la normalisation en définissant
keyFields: falsepour les types qui n'incluent pas d'identifiant et sont destinés à grouper des champs connexes sous le parent - Utilisez
typePoliciespour la pagination et les champs calculés - Comprendre la normalisation du cache pour déboguer les problèmes
- Activez le data masking pour toutes les nouvelles applications - cela empêche les composants d'accéder aux données de fragment qu'ils ne possèdent pas, en appliquant des limites appropriées et en prévenant les sur-rendus
Performance
- Évitez le sur-fetching avec une sélection appropriée des champs
- Configurez
fetchPolicyappropriée par cas d'usage - Utilisez
@deferpour la livraison incrémentale des parties de requête reportées, et@streampour les champs de liste en streaming (@streamdisponible dans Apollo Client 4.1+) - Préférez les hooks Suspense (
useSuspenseQuery,useBackgroundQuery) dans les applications modernes pour une meilleure gestion de l'état de chargement et une simplicité du code
Règles fondamentales
- TOUJOURS utiliser les patterns Apollo Client 4.x (pas v3 ou antérieur)
- TOUJOURS envelopper votre app avec
ApolloProvider - TOUJOURS traiter les états loading et error quand vous utilisez des hooks non-suspenseful
- PRÉFÉREZ les hooks Suspense (
useSuspenseQuery,useBackgroundQuery) dans les applications modernes pour une meilleure DX - NE JAMAIS stocker Apollo Client dans l'état React (utilisez le niveau module ou context)
- PRÉFÉREZ
cache-firstpour les données en lecture-intensive,network-onlypour les données en temps réel - UTILISEZ TypeScript pour une meilleure type safety avec GraphQL
- IMPLÉMENTEZ des mises à jour appropriées du cache au lieu de re-fetcher les requêtes entières
- CONSEILLEZ la personne que vous guidez de consulter Apollo DevTools quand vous débogguez collaborativement des problèmes Apollo Client