
Différences entre Server Components et Client Components
Comprenez les distinctions fondamentales entre les React Server Components (RSC) et les Client Components : environnement d'exécution, interactivité, bundle JS, accès aux données.
Deux types de composants, un seul arbre React
L'architecture introduite avec les React Server Components (RSC) repose sur la coexistence de deux types fondamentaux de composants au sein de la même application React : les Server Components et les Client Components. Bien qu'ils puissent être imbriqués et interagir, leurs capacités, leur environnement d'exécution et leur impact sur l'application finale sont radicalement différents.
Comprendre précisément ces différences est essentiel pour utiliser efficacement cette nouvelle architecture, notamment dans des frameworks comme Next.js (avec l'App Router) où ce modèle est central. Savoir quand utiliser l'un ou l'autre type est la clé pour optimiser les performances tout en conservant l'interactivité nécessaire.
Comparaison détaillée : Server vs Client
Voici un tableau récapitulant les distinctions majeures :
| Caractéristique | Server Components (RSC) | Client Components |
|---|---|---|
| Environnement d'exécution | Serveur (Node.js ou équivalent) / Pendant le build (SSG) | Navigateur Client (après hydratation si SSR/SSG) |
| Code JS dans le Bundle Client | Non (Zéro impact) | Oui (Contribue à la taille) |
| Utilisation de `useState`, `useEffect`, `useReducer` | Non | Oui |
| Utilisation des API Navigateur (`window`, `document`, `localStorage`) | Non | Oui |
| Utilisation des gestionnaires d'événements (`onClick`, `onChange`, etc.) | Non | Oui |
| Accès direct aux ressources Backend (DB, FS, API internes) | Oui | Non (Doit passer par une requête `fetch` vers une API) |
| Rendu initial | Côté serveur (en format sérialisé) | Côté client (ou serveur pour SSR/SSG, puis hydratation client) |
| Interactivité / Etat local | Aucune | Permise et gérée |
| Déclaration / Marquage | Par défaut (dans Next.js App Router) | Directive "use client"; en haut du fichier |
| Cas d'usage typiques | Affichage de données statiques ou serveur, layouts, accès direct aux données, composants sans interactivité client | Boutons interactifs, formulaires avec état, animations, composants utilisant des effets ou l'état, accès aux API navigateur |
Focus sur les différences fondamentales
- Interactivité et Etat : C'est la distinction la plus cruciale. Si un composant a besoin de réagir à des actions utilisateur (clics, saisie), de maintenir un état local qui change au fil du temps (`useState`), ou d'exécuter des effets après le rendu (`useEffect`), il doit être un Client Component (marqué avec
"use client";). Les Server Components sont purement destinés à afficher des données et une structure, sans interaction côté client. - Taille du Bundle JavaScript : C'est la motivation principale derrière les RSC. Tout le code d'un Server Component, ainsi que les bibliothèques qu'il importe et qui ne sont pas utilisées par des Client Components, restent sur le serveur. Cela peut significativement réduire la quantité de JavaScript que le client doit télécharger et exécuter, améliorant les performances, surtout sur les connexions lentes ou les appareils moins puissants.
- Accès aux Données : Les Server Components peuvent directement interroger une base de données, lire des fichiers sur le serveur, ou appeler des API internes sans exposer de secrets ou nécessiter une couche API supplémentaire. C'est un avantage majeur pour simplifier le chargement des données initiales. Les Client Components, s'exécutant dans le navigateur, doivent utiliser `fetch` ou des bibliothèques similaires pour interroger des endpoints API exposés publiquement.
Modèle d'interaction et composition
Bien qu'ils soient distincts, ces deux types de composants sont conçus pour fonctionner ensemble :
- Un Server Component PEUT importer et rendre un Client Component : C'est ainsi que l'on intègre des îlots d'interactivité dans une page majoritairement rendue côté serveur.
- Un Client Component NE PEUT PAS importer directement un Server Component : Car le code du Server Component n'est pas disponible côté client. Cependant, un Client Component peut recevoir un Server Component en tant que prop (typiquement via `children`) depuis un parent Server Component.
- Passage de Props : Les props passées d'un Server Component à un Client Component doivent être sérialisables (convertibles en JSON : chaînes, nombres, booléens, objets/tableaux simples). Vous ne pouvez pas passer de fonctions ou de types complexes comme des Dates directement comme props d'un Server vers un Client Component (sauf si le framework fournit des mécanismes spécifiques pour cela, comme les Server Actions dans Next.js).
La directive "use client"; agit comme une frontière. Une fois que vous êtes dans un module marqué `"use client"`, tous les composants ou modules qu'il importe sont considérés comme faisant partie du bundle client.
Conclusion : Choisir le bon outil pour le bon travail
La distinction entre Server Components et Client Components offre une nouvelle granularité dans la conception d'applications React. Elle permet aux développeurs de choisir délibérément où un composant doit s'exécuter en fonction de ses besoins spécifiques.
Utilisez les Server Components par défaut pour l'affichage de données, la structure, et l'accès direct au backend, afin de minimiser le JavaScript client. Optez pour les Client Components (avec "use client";) uniquement lorsque l'interactivité, l'état local, les effets de cycle de vie, ou l'utilisation d'API navigateur sont nécessaires. Maîtriser cette distinction est la clé pour tirer pleinement parti des avantages de performance et d'architecture offerts par les frameworks React modernes qui implémentent les RSC.