MohandOussadi
Retour au blog
React 19 : Actions, useOptimistic, use() et la fin de forwardRef

React 19 : Actions, useOptimistic, use() et la fin de forwardRef

21 janvier 2025
3 min de lecture
React
Frontend
Nouveautés

React 19 est sorti en version stable le 5 décembre 2024. Contrairement à certaines versions majeures centrées sur le moteur interne, celle-ci change la façon d'écrire du code au quotidien, en particulier pour les formulaires et les mutations de données. Tour d'horizon des nouveautés qui comptent.

Les Actions : la fin du trio isLoading / error / data

Pendant des années, chaque formulaire a répété le même code : un état de chargement, un état d'erreur, un try/catch, un preventDefault. React 19 introduit les Actions : des fonctions (éventuellement asynchrones) exécutées dans une transition, dont React gère automatiquement l'état en attente, les erreurs et la réinitialisation du formulaire.

Cycle d'une Action : l'interface est mise à jour immédiatement, puis confirmée ou annulée par la réponse du serveur
Cycle d'une Action : l'interface est mise à jour immédiatement, puis confirmée ou annulée par la réponse du serveur

useActionState : un formulaire en quelques lignes

"use client";
import { useActionState } from "react";
import { updateName } from "./actions";

export function NameForm() {
  const [error, submitAction, isPending] = useActionState(
    async (_previous: string | null, formData: FormData) => {
      const result = await updateName(formData.get("name") as string);
      return result.error ?? null;
    },
    null
  );

  return (
    <form action={submitAction}>
      <input name="name" required />
      <button disabled={isPending}>{isPending ? "Enregistrement…" : "Enregistrer"}</button>
      {error && <p role="alert">{error}</p>}
    </form>
  );
}

Plus de useState pour le chargement, plus de onSubmit : on passe directement une fonction à l'attribut action du formulaire. Le formulaire est réinitialisé automatiquement après succès.

Pour un bouton imbriqué dans un design system, useFormStatus (importé depuis react-dom) donne accès à l'état pending du formulaire parent sans faire descendre de props.

useOptimistic : une interface instantanée

Quand l'utilisateur ajoute un commentaire ou coche une tâche, attendre la réponse du serveur donne une impression de lenteur. useOptimistic affiche immédiatement le résultat attendu, puis revient automatiquement à l'état réel si l'action échoue.

const [optimisticTodos, addOptimisticTodo] = useOptimistic(
  todos,
  (current, newTodo: Todo) => [...current, { ...newTodo, pending: true }]
);

async function addTodo(formData: FormData) {
  const todo = { id: crypto.randomUUID(), title: formData.get("title") as string };
  addOptimisticTodo(todo);   // affichage immédiat
  await createTodo(todo);    // confirmation serveur
}

use() : lire une promesse ou un contexte

La nouvelle API use lit la valeur d'une promesse (en suspendant le rendu jusqu'à sa résolution, avec un Suspense parent) ou d'un contexte. Contrairement aux hooks, use peut être appelé dans une condition.

function Comments({ commentsPromise }: { commentsPromise: Promise<Comment[]> }) {
  const comments = use(commentsPromise);
  return comments.map((c) => <p key={c.id}>{c.text}</p>);
}

Attention : la promesse doit être créée en dehors du composant (par exemple dans un Server Component qui la transmet), sinon une nouvelle promesse est créée à chaque rendu.

Les petites nouveautés qui simplifient la vie

  • `ref` devient une prop comme les autres pour les composants fonctions : plus besoin de forwardRef, qui sera déprécié à terme.
  • `<Context>` peut être utilisé directement comme provider, à la place de <Context.Provider>.
  • Les balises `<title>`, `<meta>` et `<link>` rendues n'importe où dans l'arbre sont automatiquement remontées dans le <head>.
  • Les fonctions de nettoyage des refs : une ref callback peut retourner une fonction appelée au démontage.
  • De meilleurs messages d'erreur d'hydratation, avec un diff entre le rendu serveur et client.

Migrer sereinement

La migration depuis React 18 est généralement simple. L'équipe React recommande de passer d'abord par React 18.3, qui affiche des avertissements pour les API supprimées (propTypes et defaultProps sur les composants fonctions, anciens contextes, refs sous forme de chaînes…). Des codemods automatisent la plupart des changements.

Conclusion

React 19 rend enfin natifs des patterns que chaque équipe réécrivait à la main : gestion des formulaires, mises à jour optimistes, chargement de données avec Suspense. Combiné aux Server Actions de Next.js, il permet d'écrire des mutations complètes, du bouton à la base de données, avec très peu de code.

Partager cet article