Changer le thème

Formulaire React 19 en 30 lignes ? Actions en un clin d'œil, perf +40 %

Easton editorial illustration: rendering-mode selector

Introduction

Pour gérer la soumission d’un formulaire, il faut empiler des useState pour loading, error et data, puis enchaîner avec useEffect pour la logique de soumission — plus de 30 lignes qui donnent le tournis. Avec la sortie officielle de React 19 (5 décembre 2024), Actions, le Compiler et le Hook use() répondent précisément à ces points de friction du quotidien.

J’ai passé une semaine à creuser React 19 en profondeur et à tester les 6 fonctionnalités clés sur un projet perso. Ce n’est pas une révolution, mais ça règle des problèmes concrets qu’on rencontre tous les jours. Voyons si ces nouveautés tiennent leurs promesses.

Quels problèmes React 19 résout-il ? (vue développeur)

Avant d’entrer dans le détail, voici les douleurs que cette mise à jour vise surtout.

Les vieux problèmes des formulaires. Pour une soumission, mon schéma habituel ressemblait à ça :

// Ancienne approche React 18 — code verbeux et fragile
function LoginForm() {
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState(null);
  const [data, setData] = useState(null);
  const handleSubmit = async (e) => {
    e.preventDefault();
    setLoading(true);
    setError(null);
    try {
      const result = await loginAPI(email, password);
      setData(result);
    } catch (err) {
      setError(err.message);
    } finally {
      setLoading(false);
    }
  };
  // Et il faut encore gérer manuellement le bouton désactivé, l'affichage des erreurs...
}

C’est déjà le cas simple ; sur un formulaire complexe, la gestion des états loading et error devient vite épuisante.

La charge mentale de l’optimisation perf. Honnêtement, j’oublie souvent d’ajouter memo, et je ne suis jamais sûr de ce qu’il faut envelopper dans useMemo. Trop d’optimisation craint l’over-engineering ; pas assez, on craint la régression perf. Chaque code review devient un casse-tête.

La confusion autour des Server Components. Je voulais utiliser les Server Components de Next.js, mais la doc restait floue : quand mettre « use client » ? Comment faire collaborer composants serveur et client ? Comment passer les données ? À chaque fois, retour sur Google.

React 19 apporte de meilleures réponses à tout ça.

Actions — fini l’enfer des formulaires

C’est quoi Actions ? En bref, une nouvelle façon de gérer les opérations asynchrones : vous passez une fonction async au formulaire, et React gère pending, error et success pour vous.

La première fois que j’ai vu useActionState, j’étais perplexe. Après quelques essais : franchement, c’est top.

Exemple concret

Le même formulaire de connexion, réécrit avec Actions :

// Nouvelle approche React 19 — code plus court et plus clair
import { useActionState } from 'react';
function LoginForm() {
  // useActionState retourne : [état, fonction de soumission, en cours ?]
  const [state, submitAction, isPending] = useActionState(
    async (prevState, formData) => {
      // Valeurs du formulaire via formData, sans useState
      const email = formData.get('email');
      const password = formData.get('password');
      try {
        const result = await loginAPI(email, password);
        return { success: true, data: result };
      } catch (error) {
        return { success: false, error: error.message };
      }
    },
    { success: false, data: null, error: null } // état initial
  );
  return (
    <form action={submitAction}>
      <input name="email" type="email" />
      <input name="password" type="password" />
      {/* isPending géré automatiquement, plus de setLoading manuel */}
      <button disabled={isPending}>
        {isPending ? 'Connexion...' : 'Se connecter'}
      </button>
      {state.error && <p className="error">{state.error}</p>}
    </form>
  );
}

Avant / après

J’ai compté : ce formulaire passe d’environ 45 lignes (états, erreurs, reset) à moins de 30. Surtout, la logique est plus lisible :

  • Plus de gestion manuelle de loading / setLoading
  • Erreurs intégrées dans le retour de l’action
  • isPending disponible immédiatement
  • Données via formData, sans empiler les useState

Quand utiliser Actions ?

Trois scénarios typiques :

  1. Soumission de formulaire : login, inscription, commentaires — validation et envoi async
  2. Mise à jour de données : panier, likes, favoris, bascules d’état
  3. Opérations multi-étapes : mise à jour optimiste, encore mieux avec useOptimistic

Au début, je craignais un conflit avec les gestionnaires d’événements classiques. En pratique, les deux coexistent : logique métier complexe en mode traditionnel, formulaires en Actions — c’est très confortable.

use() — une autre façon de récupérer des données async

Pourquoi use() ?

Avant, on faisait souvent :

// Pattern classique useEffect + useState
function UserProfile({ userId }) {
  const [user, setUser] = useState(null);
  const [loading, setLoading] = useState(true);
  useEffect(() => {
    fetchUser(userId).then(data => {
      setUser(data);
      setLoading(false);
    });
  }, [userId]);
  if (loading) return <div>Chargement...</div>;
  return <div>{user.name}</div>;
}

Rien de grave, mais le boilerplate loading se répète partout.

La force de use()

Le Hook use() de React 19 peut s’appeler dans une condition — ce qui brise la règle habituelle des Hooks. Avec Suspense, le code devient nettement plus court :

import { use, Suspense } from 'react';
function UserProfile({ userId }) {
  // Attention : use() dans une condition, interdit avec les Hooks classiques
  const userPromise = userId ? fetchUser(userId) : null;
  const user = userPromise ? use(userPromise) : null;
  if (!user) return <div>Veuillez sélectionner un utilisateur</div>;
  return <div>{user.name}</div>;
}
// Suspense au parent pour centraliser le loading
function App() {
  return (
    <Suspense fallback={<div>Chargement...</div>}>
      <UserProfile userId={123} />
    </Suspense>
  );
}

Différence clé

Le changement est surtout mental :

  • useEffect : impératif — « récupérer les données, puis mettre à jour l’état »
  • use() : déclaratif — « ce composant a besoin de ces données »

Après une après-midi de tests, use() brille surtout avec les Server Components ; côté client pour des données async, c’est aussi pratique.

Pièges à éviter

Même si use() accepte les conditions, il y a des limites :

  • Uniquement en phase render, pas dans un gestionnaire d’événements
  • La Promise doit être une référence stable (useMemo si besoin)
  • Gestion des erreurs via Error Boundary

Mon premier piège : use(fetch(...)) directement — un nouveau fetch à chaque render. useMemo a réglé le problème.

React Compiler — l’optimisation perf automatique

Pour ceux qui oublient memo (avouons-le), le React Compiler est une bouée.

Que fait le Compiler ?

Il analyse votre code au build et insère automatiquement memo, useMemo et useCallback là où c’est utile — comme un assistant qui applique les optimisations à votre place.

Combien de code en moins ?

Sur un projet moyen, j’avais plus de 30 memo/useMemo manuels. Après activation du Compiler, tout supprimé — perf quasi identique, parfois meilleure. Meta indique que la mémoïsation auto réduit fortement le code d’optimisation manuel.

Comment l’activer ?

Un plugin Babel suffit :

# Installation du plugin React Compiler
npm install babel-plugin-react-compiler

Puis dans la config Babel :

// .babelrc
{
  "plugins": ["babel-plugin-react-compiler"]
}

Quand le Compiler ne suffit pas

Ce n’est pas magique :

  1. Code hors règles React : mutation de variables externes en render, par exemple
  2. Dépendances dynamiques : difficiles à analyser statiquement
  3. Compatibilité libs tierces : certaines vieilles libs demandent des tests

Mon avis : faible gain sur petit projet, net sur moyen/grand. Toujours tester avant la prod.

Server Components et gestion des ressources

Les Server Components sont la partie la plus dense de React 19. La doc m’a perdu au premier passage — une fois le principe saisi, ça résout vraiment des cas concrets.

Server Components en 5 phrases

  1. Ils tournent sur le serveur, pas dans le JavaScript client
  2. Accès direct BDD et système de fichiers, sans couche API
  3. Le rendu est envoyé au client dans un format spécial, puis affiché
  4. Mix possible avec Client Components, avec des frontières nettes
  5. Surtout pour l’affichage — l’interaction passe par les Client Components

Métadonnées document dans le composant

Avant, le SEO dans Next.js imposait des APIs dédiées. React 19 accepte <title> et <meta> directement dans le composant ; React les remonte dans <head> :

// Server Component — balises SEO dans le composant
function BlogPost({ post }) {
  return (
    <>
      {/* Ces balises remontent automatiquement dans <head> */}
      <title>{post.title} - Mon blog</title>
      <meta name="description" content={post.summary} />
      <meta property="og:image" content={post.coverImage} />
      <article>
        <h1>{post.title}</h1>
        <p>{post.content}</p>
      </article>
    </>
  );
}

Beaucoup plus simple — même en profondeur dans l’arbre, vous contrôlez title et meta.

Préchargement des ressources

React 19 gère aussi la priorité des feuilles de style :

// Feuille haute priorité — styles critiques en premier
<link rel="stylesheet" href="/critical.css" precedence="high" />
// Feuille basse priorité — styles non critiques différés
<link rel="stylesheet" href="/optional.css" precedence="low" />

Les styles critiques chargent en premier, moins de flash visuel.

SC ou CC — comment choisir ?

Ma grille de décision :

  • Server Components : affichage de données, pages SEO, accès backend
  • Client Components (avec « use client ») : interaction, APIs navigateur, état local

En mix : Server Component en enveloppe, Client Components à l’intérieur pour l’interactivité.

Piège principal

La frontière « use client » : dès que vous la posez en tête de fichier, ce composant et tous ses descendants deviennent client. Découpez finement — seule la partie interactive en Client Component.

Nettoyage des callbacks ref et Web Components

Deux fonctionnalités plus de niche, mais utiles dans certains contextes.

Fonction de nettoyage sur callback ref

Avec ref pour écouter le DOM, on oublie souvent le cleanup — fuite mémoire. React 19 permet de retourner une fonction de nettoyage depuis le callback ref :

<div ref={(node) => {
  if (node) {
    // Configuration — observer l'entrée dans le viewport
    const observer = new IntersectionObserver(() => {
      // Gérer le changement de visibilité
    });
    observer.observe(node);
    // Nettoyage automatique au démontage
    return () => {
      observer.disconnect();
    };
  }
}} />

Proche de useEffect — pratique pour intégrer des libs tierces (graphiques, cartes).

Support complet des Web Components

React 19 supporte customElements et l’API Web Components. Pour un design system maison ou du partage inter-frameworks en entreprise, c’est pertinent.

// Web Components — réutilisables entre frameworks
function App() {
  return <my-custom-element data={someData} />;
}

Je ne l’ai pas encore utilisé en prod, mais pour les grosses orgs et les équipes design system, c’est une vraie plus-value.

Guide de migration et points d’attention

Autant de promesses — faut-il migrer ? Voici comment j’ai évalué.

Breaking changes

React 19 en apporte plusieurs :

  1. propTypes retiré : migrer vers TypeScript ou supprimer
  2. defaultProps retiré (composants fonction) : valeurs par défaut sur les paramètres
  3. Legacy Context retiré : nouvelle API Context obligatoire
  4. string refs retirées : callback refs ou createRef

Ce sont surtout des API déjà obsolètes ; un projet à jour ne devrait plus les utiliser.

Stratégie progressive

Mon conseil :

  • Petit projet (<50 composants) : upgrade direct, bugs faciles à localiser
  • Projet moyen (50-200) : branche de dev, tester formulaires et listes en priorité
  • Grand projet (>200) :
    1. Pilote sur un module non critique
    2. Migration graduelle avec métriques perf
    3. Plutôt attendre Q1 2025, écosystème plus mûr

Tests de performance

Comparez avant/après :

  • Temps de premier rendu
  • Réactivité aux interactions
  • Taille du bundle
  • Mémoire à l’exécution

Sur mon projet perso : ~150 ms de gain au premier rendu avec le Compiler, bundle quasi inchangé (optimisation au build).

Écosystème

Les libs majeures supportent déjà React 19 :

  • Next.js 15 : support complet
  • Redux Toolkit, React Router v7 : compatibles
  • UI (Ant Design, Material-UI) : mises à jour en cours

Pour une lib obscure, vérifiez les issues GitHub avant de vous lancer.

Conclusion

Revenons au vendredi après-midi du début : avec React 19, ce formulaire de login tenait en ~15 lignes, sans fixer une pile de useState.

Ce n’est pas une révolution, mais ça règle des problèmes quotidiens :

  • Actions simplifient les formulaires
  • use() rend la récupération de données plus déclarative
  • React Compiler automatise l’optimisation perf
  • Server Components adressent SEO et performance
  • Nettoyage ref et Web Components complètent l’écosystème

Utilisateur React depuis la v15, j’attends cette mise à jour avec impatience. Mon plan : tout tester en perso, creuser les pièges, puis envisager une migration progressive en entreprise après le Nouvel An (Q1 2025).

Vos prochaines étapes :

  1. Essayer tout de suite : nouveau projet en React 19 pour toucher aux nouveautés
  2. Continuer à apprendre : suivre le blog officiel React, la doc est excellente
  3. Rejoindre la communauté : Discord officiel et discussions GitHub pour les dernières infos
  4. Échanger : partagez en commentaire votre expérience de migration ou vos blocages

Vous avez testé React 19 ? Actions ou Compiler vous attire le plus ? On en discute en commentaire.

Guide pratique des fonctionnalités clés de React 19

De la gestion de formulaires avec Actions aux Server Components, avec optimisation perf et stratégie de migration

Estimated time: PT2H

  1. 1

    Step 1: Simplifier les formulaires avec Actions

    Importer useActionState :
  2. 2

    Step 2: Récupérer des données async avec use()

    Importer use et Suspense :
  3. 3

    Step 3: const userPromise = userId ? fetchUser(userId)

    null;
  4. 4

    Step 4: const user = userPromise ? use(userPromise)

    null;
  5. 5

    Step 5: Note

    use() peut s’appeler dans une condition, contrairement aux Hooks classiques.
  6. 6

    Step 6: • useEffect est impératif

    « récupérer puis mettre à jour l’état »
  7. 7

    Step 7: • use() est déclaratif

    « ce composant a besoin de ces données »
  8. 8

    Step 8: Activer React Compiler pour l’optimisation auto

    Installer le plugin Babel :
  9. 9

    Step 9: Server Components et gestion des ressources

    Caractéristiques des Server Components :
  10. 10

    Step 10: • <title>{post.title}

    Mon blog</title>
  11. 11

    Step 11: • Server Components

    données, SEO, accès backend
  12. 12

    Step 12: • Client Components (avec use client)

    interaction, APIs navigateur, état
  13. 13

    Step 13: Nettoyage callback ref et Web Components

    Fonction de nettoyage sur callback ref :
  14. 14

    Step 14: Guide de migration React 19

    Breaking changes :
  15. 15

    Step 15: • Petit projet (<50 composants)

    upgrade direct
  16. 16

    Step 16: • Moyen (50-200)

    branche de test, formulaires et listes en priorité
  17. 17

    Step 17: • Grand (>200)

    pilote non critique, migration graduelle, plutôt Q1 2025
  18. 18

    Step 18: • Mesure perso

    ~150 ms de gain au premier rendu avec Compiler, bundle quasi inchangé
  19. 19

    Step 19: • Next.js 15

    support complet
  20. 20

    Step 20: • Redux Toolkit / React Router v7

    compatibles
  21. 21

    Step 21: • UI (Ant Design / Material-UI)

    mises à jour en cours
  22. 22

    Step 22: • Lib obscure

    vérifier GitHub avant migration

FAQ

Que sont les Actions dans React 19 ? Comment useActionState simplifie-t-il les formulaires ?
Les Actions sont une nouvelle façon de gérer les opérations async : vous passez une fonction async au formulaire, React gère pending, error et success.

Étapes :

1) Importer useActionState :
import { useActionState } from 'react';

2) Définir la fonction Actions :
const [state, submitAction, isPending] = useActionState(
async (prevState, formData) => {
const email = formData.get('email');
const password = formData.get('password');
try {
const result = await loginAPI(email, password);
return { success: true, data: result };
} catch (error) {
return { success: false, error: error.message };
}
},
{ success: false, data: null, error: null } // état initial
);

3) Utiliser dans le formulaire :
<form action={submitAction}>
<button disabled={isPending}>Envoyer</button>
{state.error && <p className="error">{state.error}</p>}
</form>

Avant / après :
• Formulaire de login : ~45 lignes → moins de 30
• Plus de loading/setLoading manuel
• Erreurs intégrées au retour
• isPending prêt à l'emploi
• Données via formData sans empiler les useState

Cas d'usage :
• Soumissions (login, inscription, commentaires)
• Mises à jour (panier, likes, favoris)
• Opérations multi-étapes (mise à jour optimiste avec useOptimistic)
Comment utiliser le Hook use() dans React 19 ? Quelle différence avec useEffect ?
use() peut s'appeler dans une condition — ce qui brise la règle classique des Hooks. Avec Suspense, le code devient nettement plus concis.

Étapes :

1) Importer use et Suspense :
import { use, Suspense } from 'react';

2) Utiliser use() :
const userPromise = userId ? fetchUser(userId) : null;
const user = userPromise ? use(userPromise) : null;
Note : use() dans une condition, interdit avec les Hooks classiques

3) Suspense au parent pour le loading :
<Suspense fallback={<div>Chargement...</div>}>
<UserProfile userId={123} />
</Suspense>

Différence clé :
• useEffect : impératif — « récupérer puis mettre à jour l'état »
• use() : déclaratif — « ce composant a besoin de ces données »
• use() brille avec Server Components et données async côté client

Pièges :
• Uniquement en phase render, pas dans un gestionnaire d'événements
• Promise stable (useMemo si besoin)
• Erreurs via Error Boundary
• Piège perso : use(fetch(...)) relance un fetch à chaque render — useMemo corrige
Qu'est-ce que React Compiler ? Comment activer l'optimisation automatique ?
React Compiler analyse le code au build et insère memo, useMemo et useCallback automatiquement — comme un assistant d'optimisation.

Activation :
1) npm install babel-plugin-react-compiler
2) Dans .babelrc :
{
"plugins": ["babel-plugin-react-compiler"]
}

Code supprimable :
• Projet moyen : 30+ memo/useMemo manuels retirés
• Perf stable ou meilleure
• Meta : la mémoïsation auto réduit fortement le code d'optimisation manuel

Limites :
1) Code hors règles React (mutation en render)
2) Dépendances dynamiques
3) Compatibilité libs tierces à tester

Conseil : faible gain sur petit projet, net sur moyen/grand. Tests obligatoires avant prod.
Comment utiliser les Server Components dans React 19 ? Différence avec les Client Components ?
Server Components (SC) en 5 points :
1) Exécution serveur, absent du bundle client JS
2) Accès direct BDD/FS sans API
3) Rendu envoyé au client dans un format spécial
4) Mix avec Client Components, frontières strictes
5) Surtout affichage — interactions via Client Components

Métadonnées :
• <title> et <meta> dans le composant, remontés dans <head>
• Exemple :
<title>{post.title} - Mon blog</title>
<meta name="description" content={post.summary} />
<meta property="og:image" content={post.coverImage} />
• Contrôle title/meta même en profondeur dans l'arbre

Préchargement :
• Priorité des feuilles de style
• Critique : <link rel="stylesheet" href="/critical.css" precedence="high" />
• Non critique : <link rel="stylesheet" href="/optional.css" precedence="low" />
• Moins de flash visuel

SC vs CC :
• Server Components : données, SEO, accès backend
• Client Components avec use client : interaction, APIs navigateur, état
• Mix : SC en enveloppe, CC pour l'interactivité

Piège :
• use client transforme le composant et tous ses descendants
• Découper finement, isoler l'interactivité
Quels breaking changes dans React 19 ? Comment migrer ?
Breaking changes :
1) propTypes retiré (→ TypeScript ou suppression)
2) defaultProps retiré sur composants fonction (→ valeurs par défaut des paramètres)
3) Legacy Context retiré (→ nouvelle API Context)
4) string refs retirées (→ callback refs ou createRef)

Ce sont surtout des API déjà obsolètes.

Stratégie progressive :
• <50 composants : upgrade direct
• 50-200 : branche de test, formulaires et listes
• >200 : pilote non critique, migration graduelle, plutôt Q1 2025

Tests perf :
• Premier rendu, réactivité, bundle, mémoire
• Mesure perso : ~150 ms de gain avec Compiler, bundle quasi inchangé

Écosystème :
• Next.js 15, Redux Toolkit, React Router v7 : compatibles
• Ant Design, Material-UI : mises à jour en cours
• Lib obscure : vérifier GitHub
Comment utiliser le nettoyage callback ref et le support Web Components dans React 19 ?
Nettoyage callback ref :
• Avant : oubli fréquent du cleanup sur ref DOM → fuite mémoire
• React 19 : le callback ref peut retourner une fonction de nettoyage :
<div ref={(node) => {
if (node) {
const observer = new IntersectionObserver(() => {});
observer.observe(node);
return () => {
observer.disconnect();
};
}
}} />
• Exécution auto au démontage
• Proche de useEffect — idéal pour libs tierces (graphiques, cartes)

Web Components :
• Support complet de customElements et l'API Web Components
• Exemple : <my-custom-element data={someData} />
• Pertinent pour design system maison ou réutilisation inter-frameworks
• Pas encore testé en prod perso, mais vraie plus-value pour grosses orgs et équipes design system

11 min de lecture · Publié le: 23 nov. 2025 · Mis à jour le: 27 juil. 2026

Commentaires

Connectez-vous avec GitHub pour laisser un commentaire

Easton BlogEaston Blog