Skip to Content
🎉 Utilisez JS efficacement →

🚀 Gestion des mutations avec useOptimistic dans Next.js 13+

L’optimistic UI amĂ©liore l’expĂ©rience utilisateur en affichant immĂ©diatement une mise Ă  jour de l’interface avant mĂȘme la fin du traitement serveur.
Dans Next.js 13+, on utilise useOptimistic pour gérer ces mutations cÎté client tout en tirant parti des Server Actions.


1ïžâƒŁ Pourquoi utiliser useOptimistic ?

✅ Avantages :

  • Affichage instantanĂ© des mises Ă  jour sans attendre la rĂ©ponse serveur.
  • Meilleure expĂ©rience utilisateur (rĂ©activitĂ© accrue).
  • Evite les flashs de chargement entre l’envoi et la mise Ă  jour rĂ©elle.

❌ Sans useOptimistic :

  • L’interface attend la rĂ©ponse serveur avant de s’actualiser → latence perçue.
  • Besoin de rafraĂźchir les donnĂ©es via revalidatePath() aprĂšs chaque mutation.

2ïžâƒŁ Exemple : Liste de tĂąches avec mise Ă  jour optimiste

Nous allons créer une application de gestion de tùches avec :
1ïžâƒŁ Un affichage en temps rĂ©el des tĂąches.
2ïžâƒŁ Une suppression optimiste avant confirmation serveur.


📌 Étape 1 : Server Actions pour rĂ©cupĂ©rer et supprimer une tĂąche

app/actions/todos.ts
"use server"; import { db } from "@/lib/db"; import { revalidatePath } from "next/cache"; // Récupérer les tùches export async function getTodos() { return await db.todo.findMany(); } // Supprimer une tùche export async function deleteTodo(id: string) { await db.todo.delete({ where: { id } }); // Forcer la mise à jour cÎté serveur revalidatePath("/todos"); }

✅ Explication :

  • getTodos() rĂ©cupĂšre les tĂąches.
  • deleteTodo() supprime une tĂąche et rafraĂźchit automatiquement la liste.

📌 Étape 2 : Affichage avec useOptimistic

app/todos/page.tsx
"use client"; import { useOptimistic, useState } from "react"; import { getTodos, deleteTodo } from "@/app/actions/todos"; export default function TodosPage() { const [todos, setTodos] = useState(await getTodos()); // 🎯 Utilisation de `useOptimistic` const [optimisticTodos, setOptimisticTodos] = useOptimistic( todos, // Valeur initiale (currentTodos, idToRemove) => currentTodos.filter(todo => todo.id !== idToRemove) ); async function handleDelete(id: string) { // Mise Ă  jour immĂ©diate de la liste (optimiste) setOptimisticTodos(id); // Envoi rĂ©el au serveur await deleteTodo(id); } return ( <div className="max-w-md mx-auto p-4 border rounded-lg shadow-lg"> <h1 className="text-xl font-bold mb-4">Liste des tĂąches</h1> <ul> {optimisticTodos.map((todo) => ( <li key={todo.id} className="flex justify-between border-b py-2"> {todo.title} <button onClick={() => handleDelete(todo.id)} className="text-red-500" > ✖ </button> </li> ))} </ul> </div> ); }

✅ Explication :

  • useOptimistic(todos, callback) permet de supprimer immĂ©diatement une tĂąche de la liste.
  • DĂšs le clic, la tĂąche disparaĂźt avant mĂȘme que deleteTodo() soit exĂ©cutĂ©.
  • Si la suppression Ă©choue, on peut gĂ©rer un rollback (ex. afficher un message d’erreur).

3ïžâƒŁ Comparaison : useOptimistic vs revalidatePath

đŸ”č MĂ©thodeuseOptimisticrevalidatePath
🎯 EffetMise Ă  jour immĂ©diateRafraĂźchit la page aprĂšs mutation
⚡ PerformanceInstantanĂ©Plus lent (attend la rĂ©ponse serveur)
🔄 ExpĂ©rience utilisateurUltra rĂ©actifParfois des flashs de chargement
✅ Utilisation idĂ©aleModifications visuelles rapidesDonnĂ©es critiques nĂ©cessitant une revalidation

4ïžâƒŁ GĂ©rer les erreurs (rollback en cas d’échec)

Que se passe-t-il si la suppression Ă©choue ?
On peut ajouter une gestion d’erreur avec un rollback.

handleDelete()
async function handleDelete(id: string) { const previousTodos = optimisticTodos; // Sauvegarde setOptimisticTodos(id); // Suppression instantanée try { await deleteTodo(id); } catch (error) { setOptimisticTodos(previousTodos); // Rollback en cas d'erreur } }

✅ Si deleteTodo(id) Ă©choue, la tĂąche rĂ©apparaĂźt immĂ©diatement.


🎯 Conclusion : Pourquoi useOptimistic est un game-changer ?

🚀 Avec useOptimistic, l’UI devient ultra-fluide :
✅ Moins de latence perçue → meilleures performances UX.
✅ Moins de re-rendering inutile.
✅ Gestion fine des mutations sans bloquer l’interface.

mis Ă  jour le