Guide

React en 2026, le compilateur et les composants serveur

React après ses changements, le compilateur qui enlève l'optimisation manuelle, les composants serveur, l'état des versions et ce qui mérite d'être changé.

L'équipe CodeWorlds13 min de lecture ·

Pratique JavaScript et React dans des leçons interactives avec un éditeur de code.

Crée un compte gratuit→
Dans cet article10

React reste la bibliothèque la plus utilisée pour construire des interfaces, mais la façon d'y écrire du code a changé plus ces deux dernières années que pendant les cinq précédentes. Deux changements comptent ici, et tous les deux suppriment un travail qui se faisait auparavant à la main.

Le premier est un compilateur qui s'assure lui-même que les composants ne se recalculent pas inutilement. Le second, ce sont des composants qui s'exécutent sur le serveur et qui n'envoient jamais leur code au navigateur.

Ce texte couvre ce que ces changements signifient pour le code que tu écris aujourd'hui, et ce qui mérite d'être corrigé dans du code écrit plus tôt.

La situation des versions

Commence par clarifier ce point, car les contenus en ligne mélangent souvent plusieurs choses à la fois.

La version stable aujourd'hui est la dix-neuf, sur la ligne 19.2, avec des correctifs qui sortent aussi en parallèle sur les lignes 19.1 et 19.0. Le travail sur la prochaine version avance dans des versions d'aperçu numérotées 19.3, donc tout contenu qui présente la vingt comme sortie devance les faits.

Le compilateur est un projet séparé, avec sa propre numérotation, et il a atteint sa version un à l'automne 2025. Il fonctionne avec la dix-neuf et il est prêt pour la production, ce que confirment des déploiements à grande échelle.

Les composants serveur nécessitent un framework qui les prenne en charge, car la bibliothèque fournit un mécanisme et non une solution prête à l'emploi. En pratique, cela veut dire Next.js ou un autre framework prenant en charge ce modèle.

Le compilateur, ou la fin de l'optimisation manuelle

C'est le changement qui touche le plus l'écriture de code au quotidien, et comprendre exactement ce qu'il enlève de tes épaules, ça vaut le coup.

Pendant des années, la norme consistait à envelopper des valeurs et des fonctions dans des mécanismes qui mettaient leur résultat en cache, pour qu'un composant enfant ne se recalcule pas à chaque rendu du parent. Un code plein de ces enveloppes était laid, facile à rater, et oublier une seule dépendance produisait un bug difficile à repérer.

TypeScript
const filtered = useMemo(
  () => products.filter((p) => p.category === category),
  [products, category]
)

const handleClick = useCallback(
  (id: string) => addToCart(id),
  [addToCart]
)

Le compilateur analyse le code au moment du build et ajoute lui-même ces optimisations, en fonction de ce qui se passe réellement. Le fragment ci-dessus devient du code ordinaire, sans enveloppes.

TypeScript
const filtered = products.filter((p) => p.category === category)

function handleClick(id: string) {
  addToCart(id)
}

Deux réserves méritent d'être posées. D'abord, le compilateur ne fonctionne correctement que sur du code qui respecte les règles de la bibliothèque, donc un composant qui modifie des props reçues de l'extérieur ou qui mute une variable hors de sa portée est ignoré. Des règles supplémentaires dans l'outil qui vérifie le code signalent ces endroits.

Ensuite, le code existant avec des optimisations manuelles fonctionne toujours et n'a pas besoin d'être retiré. Le compilateur s'en accommode, donc le nettoyage mérite d'être traité comme un travail fait en passant plutôt que comme une tâche séparée.

Déploie-le progressivement sur un projet existant, en activant d'abord le compilateur pour certains dossiers choisis. Ça permet de repérer les endroits qui enfreignent les règles de la bibliothèque sans arrêter tout le reste du travail.

Les composants serveur

Le second grand changement concerne l'endroit où un composant s'exécute, et il va plus loin qu'il n'y paraît au premier regard.

Un composant serveur s'exécute uniquement sur le serveur et envoie au navigateur une description du résultat plutôt que son code. Ça veut dire qu'une bibliothèque utilisée à l'intérieur d'un tel composant, un outil de traitement de dates ou un moteur de rendu de texte par exemple, n'atteint jamais le paquet envoyé à l'utilisateur.

TypeScript
async function ArticleList() {
  const articles = await db.article.findMany({ take: 20 })

  return (
    <ul>
      {articles.map((a) => (
        <li key={a.id}>{a.title}</li>
      ))}
    </ul>
  )
}

Remarque la requête vers la base de données exécutée directement dans le composant. C'est possible parce que le code ne quitte jamais le serveur, donc les identifiants d'accès restent en sécurité.

Séparer les composants serveur des composants client demande une décision pour chaque élément de l'interface, et c'est là que le malentendu apparaît le plus souvent. La règle est simple : un composant qui a besoin d'état, de gestion d'événements ou d'accès aux objets du navigateur doit être un composant client. Le reste peut rester sur le serveur.

En pratique, ça donne une organisation où la couche serveur récupère les données et construit la structure, tandis que les îlots d'interactivité sont côté client et aussi petits que possible. Le bouton qui ouvre un menu est un composant client ; la page entière autour de lui n'a pas besoin de l'être.

L'erreur la plus fréquente consiste à marquer comme client un composant situé haut dans l'arbre, car tout ce qui se trouve en dessous devient alors client aussi, et tout le bénéfice de cette séparation disparaît sans laisser de trace.

Actions et formulaires

Un troisième changement, plus discret que les deux précédents, concerne la gestion des formulaires et des opérations qui modifient des données. Ça mérite d'être connu, car ça supprime une bonne quantité de code écrit à la main.

Auparavant, gérer l'envoi d'un formulaire demandait ton propre état pour les valeurs des champs, ton propre état pour savoir si un envoi était en cours, ta propre gestion d'erreur et ta propre désactivation du bouton. Quatre choses à écrire pour chaque formulaire, et quatre endroits où oublier quelque chose.

Aujourd'hui, tu passes directement la fonction qui gère l'envoi au formulaire, et la bibliothèque expose elle-même l'information sur l'opération en cours. Désactiver le bouton et afficher un état d'attente deviennent une seule ligne au lieu d'un état séparé.

TypeScript
function SubmitButton() {
  const { pending } = useFormStatus()

  return (
    <button type="submit" disabled={pending}>
      {pending ? 'Enregistrement' : 'Enregistrer'}
    </button>
  )
}

Un mécanisme séparé gère la mise à jour immédiate de la vue, avant même la confirmation du serveur. Un commentaire ajouté apparaît tout de suite dans la liste, et si l'écriture échoue, la bibliothèque restaure elle-même l'état précédent. C'est un schéma qui s'écrivait auparavant à la main et qui laissait régulièrement l'interface dans un état incohérent après une erreur.

Fais attention à une chose. La mise à jour immédiate a du sens là où l'opération réussit presque toujours, par exemple pour un like ou l'ajout d'un commentaire. Pour un paiement ou une réservation, mieux vaut attendre la réponse, car montrer un succès qui n'a pas eu lieu est pire qu'une seconde d'attente.

Ce qu'il faut corriger dans le code existant

Trois schémas méritent d'être changés, que tu actives le compilateur ou non, car tous les trois sont source de bugs.

Le premier, c'est un effet qui calcule une valeur à partir de l'état et des props. Si une valeur peut être calculée pendant le rendu, elle n'a besoin ni d'un effet ni d'un état séparé. Ce schéma provoque un double rendu et un instant où la valeur affichée est obsolète.

Le second, c'est un effet qui synchronise l'état avec les props. Ça signifie généralement que l'état se trouve au mauvais endroit, et la solution consiste à le remonter ou à le calculer sur place.

Le troisième, c'est faire descendre des props à travers de nombreux niveaux. Une valeur transmise par cinq composants, dont aucun ne l'utilise, indique une couche de contexte manquante ou un mauvais découpage des composants.

Les trois sont détectés par l'outil présenté dans le texte sur React Doctor, qui scanne un projet et renvoie une liste de ces endroits avec leur emplacement précis.

L'état de l'application, une décision prise une fois pour toutes

La gestion d'état est un domaine où React n'impose délibérément aucune solution, donc la décision t'appartient et mérite d'être prise consciemment plutôt que par habitude.

La distinction de base concerne la provenance des données. L'état serveur, c'est tout ce qui arrive du back-end : une liste de produits, les données d'un utilisateur, des résultats de recherche. L'état client, ce sont des choses qui n'existent que dans le navigateur : un menu ouvert, le contenu d'un formulaire non envoyé, l'onglet sélectionné.

Cette distinction compte plus qu'il n'y paraît, car les deux types de données ont des besoins entièrement différents. L'état serveur demande de la récupération, de la mise en cache, du rafraîchissement et la gestion des erreurs réseau. L'état client n'a besoin de rien de tout ça et se dégrade quand on le place dans un outil conçu pour le premier.

L'erreur la plus fréquente dans les projets consiste à tout déverser dans un seul magasin global. Ça produit une couche qui réimplémente à la main la mise en cache et le rafraîchissement, c'est-à-dire des choses qu'une bibliothèque d'état serveur fait elle-même, et mieux.

Une organisation par défaut raisonnable ressemble à ceci. Les données venant du serveur sont gérées par une bibliothèque conçue pour ça, présentée dans le texte sur TanStack. L'état partagé par toute l'application, un thème ou un panier par exemple, va dans un magasin léger comme Zustand. Tout le reste reste local au composant et n'en sort jamais.

Cette dernière partie est souvent négligée, et c'est pourtant la plus importante. Le fait qu'une boîte de dialogue soit ouverte n'a pas besoin d'être global, et le sortir du composant n'apporte rien de plus qu'une chose supplémentaire à maintenir.

React face aux alternatives

SolutionForceFaiblesseQuand le choisir
ReactLe plus grand écosystème, disponibilité des développeurs, le compilateurNécessite un framework pour une utilisation complèteProjet commercial, équipe appelée à grandir
VueCourbe d'apprentissage plus douce, moins de décisionsMarché de l'emploi plus restreintÉquipe qui démarre de zéro
SvelteKitLe moins de code généré, pas de couche intermédiaireÉcosystème de bibliothèques plus restreintProjet sensible à la taille du bundle
SolidRéactivité fine sans mémoïsation, syntaxe procheCommunauté nettement plus petiteInterface avec un fort taux de mises à jour
QwikPas d'hydratation, code récupéré seulement au clicVersion 2 encore en bêta, écosystème étroitSite de contenu avec peu d'interactions

Le premier critère sur un projet commercial est banal et décisif : la disponibilité des développeurs. Une bibliothèque que la majorité du marché connaît veut dire un recrutement plus facile et une meilleure chance que quelqu'un reprenne le projet après toi.

Le second, c'est l'écosystème. Pour les besoins courants, des formulaires aux tableaux en passant par les graphiques, les solutions prêtes à l'emploi sont ici plus nombreuses et plus matures que n'importe où ailleurs.

Cet écosystème comprend une couche facile à oublier au moment de planifier : construire des composants isolés de l'application. Storybook permet de voir chaque état d'un composant séparément et de tester les interactions sans cliquer à travers la moitié du produit pour atteindre un seul formulaire. Le coût, c'est une configuration séparée à maintenir, donc sur une équipe de deux personnes, c'est souvent superflu.

Le troisième argument, défavorable cette fois, c'est la complexité. Utiliser pleinement les possibilités actuelles demande un framework, une compréhension de la séparation entre serveur et client, et une conscience de ce que fait le compilateur. Sur un site simple, c'est superflu.

Par où commencer l'apprentissage

L'ordre d'apprentissage a changé avec la bibliothèque, et une partie des contenus en ligne enseigne aujourd'hui des choses qui ont cessé d'être nécessaires.

Commence par les composants et le passage des props, car c'est le fondement, et il n'a pas changé. Ensuite, l'état local et la gestion des événements, c'est-à-dire tout ce qu'il faut pour construire une interface qui fonctionne.

Repousse les effets de bord plus loin que ne le font la plupart des cours. C'est le mécanisme le plus utilisé à mauvais escient de toute la bibliothèque, et une bonne partie des usages enseignés par les contenus plus anciens ont aujourd'hui de meilleures réponses : la récupération de données est gérée par une bibliothèque séparée ou par un composant serveur, et le calcul des valeurs se fait pendant le rendu.

Laisse complètement de côté l'optimisation manuelle au début. Le compilateur s'en occupe, donc le temps passé à apprendre les mécanismes de mise en cache de résultat est mieux investi à comprendre quand un composant se rerend et pourquoi.

Laisse la séparation serveur et client pour le moment où tu passeras à un framework. Sans lui, ce mécanisme ne fonctionnera de toute façon pas, et des concepts introduits trop tôt brouillent l'image plus qu'ils n'aident.

Vérifie la date de tout contenu que tu choisis. Un cours vieux de trois ans enseigne correctement les bases et tout le reste de façon dépassée, et reconnaître cette frontière sans expérience est difficile.

Erreurs courantes

La première, c'est un effet là où un calcul pendant le rendu suffirait. Le schéma le plus courant dans le code React et une source de doubles rendus.

La seconde, c'est marquer comme client un composant situé haut dans l'arbre. Tout ce qui se trouve en dessous devient alors client, et le bénéfice des composants serveur disparaît.

La troisième, c'est ajouter des optimisations manuelles alors que le compilateur est activé. Ça ne fait pas de mal, mais c'est un travail redondant que le compilateur effectue déjà lui-même.

La quatrième, c'est enfreindre les règles de la bibliothèque, par exemple modifier des props reçues. Le compilateur ignore ces composants, donc tu perds l'optimisation exactement là où le code est le plus suspect.

La cinquième, c'est garder dans l'état une valeur qui peut être calculée. Chaque état supplémentaire est un endroit de plus où les choses peuvent diverger.

La sixième, c'est s'appuyer sur des contenus qui décrivent une version qui n'est pas encore sortie. La version stable aujourd'hui est la dix-neuf sur la ligne 19.2, et le compilateur a sa propre numérotation.

FAQ

Quelle version de React est actuelle ?

La dix-neuf est stable sur la ligne 19.2, avec des correctifs qui sortent aussi sur les lignes 19.1 et 19.0. Le travail suivant avance dans des versions d'aperçu numérotées 19.3, donc la vingt n'existe pas. Le compilateur est un projet séparé avec sa propre numérotation, qui a atteint sa version un à l'automne 2025.

Le compilateur remplace-t-il l'optimisation manuelle ?

Oui, dans du code nouveau, tu n'as plus besoin d'envelopper des valeurs ou des fonctions dans des mécanismes de mise en cache de résultat. Le code existant avec de telles enveloppes fonctionne toujours et n'a pas besoin d'être retiré, donc nettoie-le au fil des autres changements.

Les composants serveur nécessitent-ils un framework ?

Oui. La bibliothèque fournit un mécanisme, et sa prise en charge revient au framework. En pratique, cela veut dire Next.js ou une autre solution prenant en charge ce modèle de rendu.

Quand un composant doit-il être côté client ?

Quand il a besoin d'état, de gestion d'événements ou d'accès aux objets du navigateur. Le reste peut rester sur le serveur. Marque comme client l'élément le plus bas possible dans l'arbre, car tout ce qui se trouve en dessous hérite de ce marquage.

Vaut-il la peine de démarrer un nouveau projet avec React ?

Sur un projet commercial, généralement oui, surtout pour la disponibilité des développeurs et la maturité de l'écosystème. Sur un simple site d'information ou un projet sensible à la taille du bundle, des solutions plus légères méritent d'être envisagées.

La documentation se trouve sur le site du projet, et l'historique des versions dans la liste des versions.

À lire aussi