React 19 : Actions, UI Optimiste et Nouveautés

React 19 : Actions, UI Optimiste et Nouveautés

Un tour des fonctionnalités React 19 — Actions de formulaire, useOptimistic, ref comme prop et métadonnées de document améliorées.

8 avril 202611 min de lecturePar Shehzad Asadullah

React 19 est sorti en version stable avec des fonctionnalités qui changent fondamentalement la façon dont les développeurs gèrent les formulaires, les mises à jour optimistes, les refs et les métadonnées de document. Ces ajouts réduisent le boilerplate, améliorent l'expérience utilisateur pendant les opérations async et rapprochent React d'une expérience de framework full-stack. Ce guide couvre les fonctionnalités phares que tout développeur React devrait comprendre et adopter en 2026.

Vue d'ensemble des fonctionnalités React 19 incluant Actions, useOptimistic et le support natif des métadonnées de document
React 19 introduit les Actions pour la gestion async des formulaires, useOptimistic pour un retour UI instantané et la gestion native des métadonnées.

Actions : gestion async simplifiée des formulaires

Les Actions sont des fonctions async passées aux éléments de formulaire que React gère automatiquement. Lorsqu'un utilisateur soumet un formulaire avec une action, React gère l'état pending, les error boundaries et les mises à jour optimistes sans boilerplate useState manuel pour les flags de chargement et d'erreur.

Avant React 19, gérer la soumission de formulaire nécessitait une gestion d'état explicite :

  • Suivre l'état de chargement avec useState.
  • Empêcher la double soumission manuellement.
  • Gérer les erreurs dans des blocs try/catch.
  • Réinitialiser l'état du formulaire après soumission réussie.
  • Coordonner avec Suspense pour les mutations de données côté serveur.

Les Actions consolident cela en un modèle déclaratif. Définissez une fonction async, passez-la à la prop action du formulaire, et React fournit le reste via des hooks comme useActionState et useFormStatus.

// Server Action (Next.js)
"use server";

async function createPost(prevState, formData) {
  const title = formData.get("title");
  const body = formData.get("body");

  if (!title || title.length < 3) {
    return { error: "Title must be at least 3 characters." };
  }

  await db.posts.create({ title, body });
  revalidatePath("/posts");
  return { success: true };
}

// Client Component
"use client";
import { useActionState } from "react";

function CreatePostForm() {
  const [state, formAction, isPending] = useActionState(createPost, null);

  return (
    <form action={formAction}>
      <input name="title" disabled={isPending} />
      <textarea name="body" disabled={isPending} />
      {state?.error && <p>{state.error}</p>}
      <button type="submit" disabled={isPending}>
        {isPending ? "Creating..." : "Create Post"}
      </button>
    </form>
  );
}

Le hook useFormStatus permet aux composants enfants d'accéder à l'état pending du formulaire parent sans prop drilling. Un bouton de soumission profond dans l'arbre des composants peut se désactiver automatiquement lorsque le formulaire est en cours de soumission.

useOptimistic : retour UI instantané

La latence réseau crée un écart perceptible entre l'action utilisateur et la confirmation serveur. Les utilisateurs attendent un retour instantané — basculer un bouton like, ajouter un article au panier ou marquer une tâche complète doit sembler immédiat même lorsque la requête serveur prend des centaines de millisecondes.

useOptimistic maintient une version optimiste de l'état qui se met à jour immédiatement sur action utilisateur et revient automatiquement si l'opération async échoue. Cela élimine la logique de rollback manuelle qui nécessitait auparavant une coordination d'état minutieuse.

import { useOptimistic, useTransition } from "react";

function MessageList({ messages, sendMessage }) {
  const [optimisticMessages, addOptimistic] = useOptimistic(
    messages,
    (current, newMessage) => [...current, { ...newMessage, sending: true }]
  );
  const [isPending, startTransition] = useTransition();

  function handleSend(text) {
    const tempMessage = { id: crypto.randomUUID(), text, sending: true };
    startTransition(async () => {
      addOptimistic(tempMessage);
      await sendMessage(text);
    });
  }

  return (
    <ul>
      {optimisticMessages.map((msg) => (
        <li key={msg.id} style={{ opacity: msg.sending ? 0.6 : 1 }}>
          {msg.text}
        </li>
      ))}
    </ul>
  );
}

Combinez useOptimistic avec les Actions pour un pipeline de mutation optimiste complet. L'utilisateur voit un retour immédiat, le serveur traite la requête en arrière-plan, et React réconcilie l'état optimiste avec la réponse serveur autoritaire automatiquement.

Ref en tant que prop

Avant React 19, passer des refs à des composants personnalisés nécessitait de les envelopper avec forwardRef, ajoutant de la cérémonie à chaque composant devant exposer un nœud DOM. React 19 traite ref comme une prop ordinaire, éliminant le besoin de forwardRef dans le nouveau code.

// React 19 — ref is a standard prop
function TextInput({ ref, label, ...props }) {
  return (
    <label>
      {label}
      <input ref={ref} {...props} />
    </label>
  );
}

// Usage — no change for consumers
function Form() {
  const inputRef = useRef(null);
  return <TextInput ref={inputRef} label="Email" />;
}

Ce changement simplifie les bibliothèques de composants et réduit la courbe d'apprentissage pour les développeurs découvrant le ref forwarding pour la première fois. Les composants forwardRef existants continuent de fonctionner, donc la migration est progressive plutôt que cassante.

Fonctions de nettoyage pour les refs

React 19 supporte également le retour de fonctions de nettoyage depuis les callbacks ref. Lorsqu'un composant se démonte ou que la ref change, React appelle la fonction de nettoyage, permettant une gestion correcte des ressources pour les bibliothèques tierces qui s'attachent aux nœuds DOM.

<div
  ref={(node) => {
    if (node) {
      const observer = new IntersectionObserver(handleIntersect);
      observer.observe(node);
      return () => observer.disconnect();
    }
  }}
/>

Support des métadonnées de document

Gérer les métadonnées de document — titre, description, balises Open Graph, liens canoniques — nécessitait auparavant des bibliothèques tierces comme React Helmet ou des composants head spécifiques au framework. React 19 fournit un support natif pour rendre les balises de métadonnées n'importe où dans l'arbre des composants.

Rendez les éléments title, meta et link directement dans vos composants, et React les remonte automatiquement vers l'en-tête du document :

function BlogPost({ post }) {
  return (
    <article>
      <title>{post.title} | My Blog</title>
      <meta name="description" content={post.excerpt} />
      <meta property="og:title" content={post.title} />
      <meta property="og:image" content={post.coverImage} />
      <link rel="canonical" href={`https://example.com/blog/${post.slug}`} />

      <h1>{post.title}</h1>
      <div>{post.content}</div>
    </article>
  );
}

Cette fonctionnalité s'intègre parfaitement au streaming SSR. Les métadonnées rendues par les composants serveur apparaissent dans la réponse HTML initiale, garantissant que les crawlers de moteurs de recherche et les bots d'aperçu des réseaux sociaux reçoivent des balises head complètes sans attendre l'exécution JavaScript côté client.

Améliorations supplémentaires

React 19 regroupe plusieurs améliorations plus petites qui améliorent collectivement l'expérience développeur et utilisateur :

  • Hook use() — Lisez des ressources comme des promesses et du contexte directement dans le rendu, en s'intégrant à Suspense pour les données async.
  • Context en tant que provider — Rendez <Context> directement au lieu de <Context.Provider>, réduisant le bruit syntaxique.
  • Messages d'erreur d'hydratation améliorés — Les diffs de mismatch montrent exactement quelle sortie serveur et client différaient.
  • Support des Web Components — Les éléments personnalisés s'intègrent au pipeline de rendu React sans cas spécial.
  • Améliorations du batching — Le batching automatique couvre désormais plus de scénarios async, réduisant les re-rendus inutiles.

Considérations de migration

La mise à niveau vers React 19 est conçue pour être incrémentale. La plupart des applications React 18 fonctionnent sans changements, mais plusieurs API dépréciées ont été supprimées dans la release stable. Auditez votre codebase pour ces modèles avant la mise à niveau :

  • Remplacez ReactDOM.render par createRoot si pas déjà migré.
  • Supprimez les string refs et l'usage de l'ancienne API context.
  • Mettez à jour les utilitaires de test — le comportement de react-test-renderer a changé pour les fonctionnalités concurrentes.
  • Vérifiez la compatibilité des bibliothèques tierces, surtout animation et drag-and-drop qui interagissent avec les refs.
  • Adoptez le nouveau transform JSX si vous utilisez encore le runtime classique.

React 19 représente une maturation du modèle React plutôt qu'un changement de paradigme. Les Actions et useOptimistic adressent les points de douleur les plus courants dans la gestion des formulaires et l'UI async. Ref-as-prop et les métadonnées de document suppriment la friction des tâches de développement quotidiennes. Ensemble, ces fonctionnalités vous permettent d'écrire moins de boilerplate tout en offrant de meilleures expériences utilisateur — la marque d'une évolution de framework bien conçue.

Cette lecture vous a plu ?

Un projet ou une idée en tête ? J'aimerais beaucoup en discuter.

Me contacter