Contactez-nous

Modèle mental et utilisation

Comprenez le nouveau modèle mental nécessaire pour développer avec les React Server Components (RSC) et les Client Components, et comment les utiliser efficacement ensemble.

Changement de perspective : Du Client-Centric au Server-First

L'introduction des React Server Components (RSC) nécessite un ajustement du modèle mental pour les développeurs habitués à l'approche traditionnelle des Single Page Applications (SPA) centrée sur le client. Historiquement, avec des outils comme Create React App, la plupart des composants étaient conçus pour s'exécuter dans le navigateur. Avec les RSC, notamment dans des frameworks comme Next.js App Router, l'approche par défaut devient "server-first".

Le nouveau modèle mental consiste à considérer que, par défaut, un composant est un Server Component. Il s'exécute sur le serveur, n'a pas d'état interactif côté client, et peut accéder directement aux données backend. On n'opte pour un Client Component (en ajoutant la directive "use client";) que lorsque c'est absolument nécessaire, c'est-à-dire quand le composant requiert de l'interactivité, de l'état local, des effets de cycle de vie ou l'accès aux API du navigateur.

La règle d'or : Server par défaut, Client par nécessité

Lorsque vous créez un nouveau composant dans une architecture RSC (comme Next.js App Router) :

  1. Commencez par le considérer comme un Server Component. Peut-il accomplir sa tâche sans état (`useState`), sans effets (`useEffect`) et sans interaction utilisateur directe (`onClick`, etc.) ? Peut-il récupérer ses données initiales directement depuis le backend ? Si oui, laissez-le comme Server Component.
  2. Identifiez le besoin d'interactivité ou d'API client : Si le composant doit répondre à des clics, gérer une saisie de formulaire avec état, utiliser des animations basées sur `useEffect`, ou accéder à `localStorage` ou `window`, alors il doit être un Client Component.
  3. Ajoutez `"use client";` : Si la réponse à la question précédente est oui, ajoutez la directive "use client"; tout en haut du fichier pour le transformer explicitement en Client Component.

Cette approche maximise les avantages des RSC (réduction du bundle JS) en ne rendant "client" que les parties de l'application qui en ont réellement besoin.

Composition : Imbriquer Server et Client Components

Le modèle permet une composition flexible entre les deux types :

  • Server rendant Client : C'est le cas le plus courant pour ajouter de l'interactivité. Un Server Component (ex: une page, un layout) peut importer et rendre directement un Client Component (ex: un bouton interactif, un formulaire de recherche).
    // app/page.tsx (Server Component par défaut)
    import ClientButton from './ClientButton'; // ClientButton a "use client";
    
    async function getData() { /* ... fetch data ... */ return { message: 'Data from server' }; }
    
    export default async function HomePage() {
      const data = await getData();
      return (
        

    Bienvenue (Server Component)

    {data.message}

    {/* Un Server Component rend un Client Component */}
    ); } // app/ClientButton.tsx "use client"; // Marqueur Client Component import React, { useState } from 'react'; export default function ClientButton() { const [count, setCount] = useState(0); return ( ); }
  • Client rendant Server (via Props/Children) : Un Client Component ne peut pas importer un Server Component directement. Cependant, il peut recevoir un Server Component (ou du JSX rendu par un Server Component) via ses props, notamment la prop `children`. Cela permet de créer des "layouts" ou des composants interactifs qui enveloppent du contenu statique ou généré côté serveur.
    // app/ClientLayout.tsx
    "use client";
    import React, { useState } from 'react';
    
    export default function ClientLayout({ children }: { children: React.ReactNode }) {
      const [isOpen, setIsOpen] = useState(true);
      return (
        
    {isOpen && children} {/* Rend les enfants (potentiellement Server Components) */}
    ); } // app/page.tsx (Server Component) import ClientLayout from './ClientLayout'; import ServerContent from './ServerContent'; // Autre Server Component export default function Page() { return ( {/* Passe un Server Component comme enfant à un Client Component */} ); }

La frontière `"use client";`

La directive "use client"; marque la limite entre le monde serveur et le monde client. Tout module qui importe un module marqué avec `"use client";` devient lui-même partie intégrante du bundle JavaScript client.

Cela a une implication importante : essayez de placer la directive "use client"; le plus bas possible dans votre arbre de composants (aux "feuilles" interactives). Si vous marquez un composant de layout de haut niveau comme Client Component, tous les composants qu'il importe directement ou indirectement seront également inclus dans le bundle client, même s'ils pourraient être des Server Components autrement. Utilisez le pattern `children` (comme dans l'exemple `ClientLayout` ci-dessus) pour permettre à des Client Components d'envelopper du contenu Server Component sans tirer tout l'arbre vers le client.

Gestion des données et des Props

  • Data Fetching : Préférez le data fetching direct dans les Server Components pour les données initiales. Pour les mises à jour de données déclenchées côté client, utilisez les approches traditionnelles (`fetch` dans des Client Components, potentiellement avec des bibliothèques comme React Query/SWR) ou les mécanismes fournis par le framework (comme les Server Actions de Next.js).
  • Props sérialisables : Rappelez-vous que les props passées d'un Server Component à un Client Component doivent être sérialisables (pas de fonctions, de Dates, etc., sauf si géré spécifiquement par le framework).

Conclusion : Penser en termes d'environnement

Le développement avec React Server Components vous amène à réfléchir consciemment à l'environnement d'exécution de chaque partie de votre interface utilisateur. Le modèle par défaut est le serveur, optimisé pour la performance et l'accès aux données. L'exécution côté client, marquée par "use client";, est réservée aux parties nécessitant de l'interactivité et l'accès aux API du navigateur.

En maîtrisant la distinction entre Server et Client Components, en comprenant comment ils interagissent, et en plaçant judicieusement la frontière `"use client";`, vous pouvez construire des applications React qui sont à la fois riches en fonctionnalités, interactives, et significativement plus performantes en tirant le meilleur parti des deux environnements.