L'Écosystème React
React n'est pas un framework monolithique : c'est une bibliothèque de composants UI. Tout le reste — routing, formulaires, fetching, animations, graphiques — repose sur un écosystème de librairies maintenues par la communauté.
La bonne nouvelle ? Vous n'avez pas à tout réinventer. Pour chaque problème courant, il existe probablement une librairie battle-tested, utilisée en production par des milliers d'entreprises.
La philosophie React
React encourage la composabilité : assemblez les bonnes briques plutôt que de tout construire vous-même. Choisir la bonne librairie pour le bon problème est une compétence essentielle du développeur React.
Les outils que vous connaissez déjà — et leurs alternatives
Vous avez déjà utilisé plusieurs outils dans ce cours. Voyons où ils se situent dans l'écosystème et quelles alternatives existent.
Build tool : Vite
Vous utilisez Vite pour créer et bundler vos projets React. C'est le standard actuel pour les nouveaux projets.
| Outil | Description | Statut |
|---|---|---|
| Vite | Build tool ultra-rapide, HMR instantané | ✅ Recommandé |
| Create React App | Ancien outil officiel de Meta | ❌ Déprécié (2023) |
| Next.js | Framework fullstack (SSR, SSG, API routes) | ✅ Pour les projets fullstack |
| Remix | Framework fullstack axé sur les standards web | ✅ Alternative à Next.js |
Vite vs Next.js
Vite est parfait pour les SPA (Single Page Applications) comme celles que vous construisez en cours.
Next.js est le choix quand vous avez besoin de Server-Side Rendering (SSR), de Static Site Generation (SSG), ou d'API routes intégrées. C'est le framework recommandé par l'équipe React elle-même pour les nouveaux projets en production.
Routing : React Router DOM
Vous utilisez React Router DOM pour la navigation. C'est la librairie de routing la plus populaire.
| Outil | Description | Points forts |
|---|---|---|
| React Router DOM | Standard de facto, mature | ✅ Énorme communauté, bien documenté |
| TanStack Router | Nouvelle génération, 100% type-safe | ✅ Typage complet, recherche type-safe |
// React Router DOM (ce que vous connaissez)
<Route path="/users/:id" element={<UserPage />} />
// TanStack Router (alternative type-safe)
const userRoute = createRoute({
path: '/users/$id',
component: UserPage,
validateSearch: z.object({ tab: z.string().optional() }),
})
Validation : Zod
Vous utilisez Zod pour la validation. Voici les alternatives :
| Outil | Description | Points forts |
|---|---|---|
| Zod | Validation type-safe, standard moderne | ✅ Inférence TypeScript, zero-dependency |
| Yup | Historiquement populaire | Bon écosystème, moins type-safe |
| Valibot | Ultra-léger, tree-shakable | ✅ ~1kb vs ~8kb pour Zod |
Valibot : l'alternative légère
Valibot est une alternative récente à Zod avec une API similaire mais un bundle beaucoup plus petit grâce au tree-shaking. Si la taille du bundle est critique pour votre projet, Valibot mérite un coup d'œil.
// Zod
import { z } from 'zod';
const schema = z.object({ name: z.string().min(3) });
// Valibot (API similaire, bundle plus petit)
import * as v from 'valibot';
const schema = v.object({ name: v.pipe(v.string(), v.minLength(3)) });
Pourquoi Next.js est-il recommandé pour les projets en production plutôt que Vite seul ?
Gestion des formulaires — React Hook Form
Le problème
Vous avez appris à créer des formulaires avec useState. Ça fonctionne, mais sur des formulaires complexes (10+ champs), ça devient verbeux et chaque frappe clavier provoque un re-render du composant entier.
// ❌ Avec useState : verbeux et re-renders à chaque frappe
function SignupForm() {
const [name, setName] = useState('');
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [confirmPassword, setConfirmPassword] = useState('');
const [age, setAge] = useState('');
// ... un useState par champ, ça s'accumule vite !
}
La solution : React Hook Form
React Hook Form utilise des refs au lieu de state, ce qui évite les re-renders inutiles. Il s'intègre parfaitement avec Zod via @hookform/resolvers.
npm install react-hook-form @hookform/resolvers
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { z } from 'zod';
const schema = z.object({
name: z.string().min(2, 'Au moins 2 caractères'),
email: z.string().email('Email invalide'),
age: z.number().min(18, 'Minimum 18 ans'),
});
type FormData = z.infer<typeof schema>;
function SignupForm() {
const { register, handleSubmit, formState: { errors } } = useForm<FormData>({
resolver: zodResolver(schema),
});
const onSubmit = (data: FormData) => {
console.log('Données validées :', data); // Type-safe !
};
return (
<form onSubmit={handleSubmit(onSubmit)}>
<input {...register('name')} placeholder="Nom" />
{errors.name && <span>{errors.name.message}</span>}
<input {...register('email')} placeholder="Email" />
{errors.email && <span>{errors.email.message}</span>}
<input {...register('age', { valueAsNumber: true })} placeholder="Age" type="number" />
{errors.age && <span>{errors.age.message}</span>}
<button type="submit">S'inscrire</button>
</form>
);
}
React Hook Form + Zod = le combo parfait
- React Hook Form gère les formulaires (performance, soumission, états)
- Zod gère la validation (règles, types, messages d'erreur)
register('name')retourne les propsonChange,onBlur,ref— pas besoin deuseState!
Data Fetching — TanStack Query
Le problème
Vous avez appris à fetch des données avec useEffect + useState. Ce pattern fonctionne, mais il manque beaucoup de choses : cache, refetch automatique, invalidation, gestion d'erreur avancée...
// ❌ Le pattern classique : répétitif et sans cache
function UserList() {
const [users, setUsers] = useState([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
fetch('/api/users')
.then(res => res.json())
.then(data => setUsers(data))
.catch(err => setError(err))
.finally(() => setLoading(false));
}, []);
// ... gérer loading, error, data à chaque fois
}
La solution : TanStack Query
TanStack Query (anciennement React Query) gère tout ça automatiquement : cache, refetch, loading/error states, pagination, et plus encore.
npm install @tanstack/react-query
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
// Lire des données
function UserList() {
const { data: users, isLoading, error } = useQuery({
queryKey: ['users'],
queryFn: () => fetch('/api/users').then(res => res.json()),
});
if (isLoading) return <p>Chargement...</p>;
if (error) return <p>Erreur : {error.message}</p>;
return (
<ul>
{users.map(user => <li key={user.id}>{user.name}</li>)}
</ul>
);
}
// Écrire des données (POST, PUT, DELETE)
function CreateUser() {
const queryClient = useQueryClient();
const mutation = useMutation({
mutationFn: (newUser) => fetch('/api/users', {
method: 'POST',
body: JSON.stringify(newUser),
}),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['users'] }); // Rafraîchit la liste !
},
});
return <button onClick={() => mutation.mutate({ name: 'Alice' })}>Ajouter</button>;
}
Pourquoi TanStack Query ?
- ✅ Cache automatique : les données ne sont pas re-fetchées inutilement
- ✅ Refetch intelligent : au focus de la fenêtre, à la reconnexion réseau
- ✅ Invalidation : quand vous modifiez des données, les listes se mettent à jour
- ✅ Loading/Error/Success : gérés automatiquement
- ✅ DevTools : un panneau pour inspecter le cache en temps réel
Quel est l'avantage principal de TanStack Query par rapport au pattern useEffect + fetch ?
Visualisation de données — Recharts
Quand vous devez afficher des graphiques (barres, lignes, camemberts...), inutile de dessiner du SVG à la main. Recharts est la librairie la plus populaire pour les graphiques en React.
npm install recharts
import { LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip } from 'recharts';
const data = [
{ mois: 'Jan', ventes: 400 },
{ mois: 'Fev', ventes: 300 },
{ mois: 'Mar', ventes: 600 },
{ mois: 'Avr', ventes: 800 },
{ mois: 'Mai', ventes: 500 },
];
function SalesChart() {
return (
<LineChart width={600} height={300} data={data}>
<CartesianGrid strokeDasharray="3 3" />
<XAxis dataKey="mois" />
<YAxis />
<Tooltip />
<Line type="monotone" dataKey="ventes" stroke="#8884d8" strokeWidth={2} />
</LineChart>
);
}
Alternatives à Recharts
- Chart.js (via
react-chartjs-2) : Très populaire, nombreux types de graphiques - Nivo : Graphiques soignés, animé par défaut
- Victory : API déclarative, bonne documentation
- Tremor : Composants de dashboard pré-stylés (construit sur Recharts)
3D et Animations
React Three Fiber — La 3D dans React
React Three Fiber est un wrapper React pour Three.js, la référence en 3D sur le web. Il permet de créer des scènes 3D avec la syntaxe déclarative de React.
npm install three @react-three/fiber @react-three/drei
import { Canvas } from '@react-three/fiber';
import { OrbitControls } from '@react-three/drei';
function RotatingCube() {
return (
<mesh rotation={[0.5, 0.5, 0]}>
<boxGeometry args={[1, 1, 1]} />
<meshStandardMaterial color="royalblue" />
</mesh>
);
}
function Scene() {
return (
<Canvas style={{ height: '400px' }}>
<ambientLight intensity={0.5} />
<pointLight position={[10, 10, 10]} />
<RotatingCube />
<OrbitControls />
</Canvas>
);
}
Quand utiliser React Three Fiber ?
- Visualisations 3D interactives
- Configurateurs de produits (e-commerce)
- Jeux simples dans le navigateur
- Animations 3D avancées
Le package @react-three/drei fournit des helpers prêts à l'emploi : contrôles de caméra, textes 3D, loaders de modèles, etc.
Framer Motion — Animations déclaratives
Framer Motion permet d'animer vos composants React de manière déclarative, sans CSS complexe ni JavaScript impératif.
npm install framer-motion
import { motion } from 'framer-motion';
function AnimatedCard() {
return (
<motion.div
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.5 }}
whileHover={{ scale: 1.05 }}
whileTap={{ scale: 0.95 }}
className="card"
>
<h3>Je suis animée !</h3>
</motion.div>
);
}
Framer Motion en bref
initial: état de départ de l'animationanimate: état finaltransition: durée, easing, délaiwhileHover/whileTap: animations interactivesexit: animation de sortie (avecAnimatePresence)
Composants UI — Radix UI / shadcn/ui
Le problème des composants UI
Construire un select, un dialog, un dropdown menu ou un accordion accessibles et fonctionnels est beaucoup plus complexe qu'il n'y paraît. Il faut gérer le clavier, l'accessibilité (ARIA), le focus trapping, etc.
Headless UI : Radix UI
Radix UI fournit des composants headless (sans style) qui gèrent toute la logique et l'accessibilité. Vous ajoutez votre propre style.
import * as Dialog from '@radix-ui/react-dialog';
function MyDialog() {
return (
<Dialog.Root>
<Dialog.Trigger>Ouvrir</Dialog.Trigger>
<Dialog.Portal>
<Dialog.Overlay className="overlay" />
<Dialog.Content className="dialog">
<Dialog.Title>Mon Dialog</Dialog.Title>
<Dialog.Description>Contenu accessible et fonctionnel.</Dialog.Description>
<Dialog.Close>Fermer</Dialog.Close>
</Dialog.Content>
</Dialog.Portal>
</Dialog.Root>
);
}
shadcn/ui : le meilleur des deux mondes
shadcn/ui n'est pas une librairie traditionnelle — c'est une collection de composants que vous copiez dans votre projet. Ils sont construits sur Radix UI + Tailwind CSS.
# Ajouter un composant
npx shadcn@latest add button
npx shadcn@latest add dialog
npx shadcn@latest add select
// Le composant est copié dans votre projet — vous le possédez !
import { Button } from '@/components/ui/button';
function MyPage() {
return (
<div>
<Button variant="default">Primaire</Button>
<Button variant="outline">Outline</Button>
<Button variant="destructive">Supprimer</Button>
</div>
);
}
Pourquoi shadcn/ui ?
- ✅ Vous possédez le code : les composants sont dans votre projet, pas dans
node_modules - ✅ Entièrement personnalisable : modifiez le code source directement
- ✅ Accessible : construit sur Radix UI
- ✅ Beau par défaut : style Tailwind CSS soigné
- ✅ Pas de dépendance : pas de version à maintenir
Gestion d'état globale — Zustand
Le problème
La Context API de React fonctionne pour partager un état simple, mais elle a des limites :
- Verbeux (Provider, Context, useContext)
- Re-renders excessifs si mal utilisée
- Pas de devtools intégrées
La solution : Zustand
Zustand (mot allemand pour "état") est une librairie de gestion d'état minimaliste et performante.
npm install zustand
import { create } from 'zustand';
// Créer un store en 5 lignes
const useCartStore = create((set) => ({
items: [],
addItem: (item) => set((state) => ({
items: [...state.items, item],
})),
removeItem: (id) => set((state) => ({
items: state.items.filter(item => item.id !== id),
})),
clearCart: () => set({ items: [] }),
}));
// Utiliser dans n'importe quel composant — sans Provider !
function CartIcon() {
const itemCount = useCartStore((state) => state.items.length);
return <span>Panier ({itemCount})</span>;
}
function CartPage() {
const { items, removeItem, clearCart } = useCartStore();
return (
<div>
{items.map(item => (
<div key={item.id}>
{item.name} <button onClick={() => removeItem(item.id)}>X</button>
</div>
))}
<button onClick={clearCart}>Vider le panier</button>
</div>
);
}
Zustand vs Context API
| Context API | Zustand | |
|---|---|---|
| Setup | Provider + Context + useContext | create() + hook |
| Re-renders | Tous les consumers re-render | Seulement si la valeur sélectionnée change |
| DevTools | Non | Oui (middleware) |
| Persistance | Manuelle | Middleware intégré |
| Courbe d'apprentissage | Faible | Faible |
Règle simple : Context API pour un état simple (thème, langue). Zustand pour un état complexe (panier, authentification, filtres).
Autres librairies utiles
L'écosystème React est vaste. Voici quelques librairies supplémentaires à garder en tête :
| Catégorie | Librairie | Description |
|---|---|---|
| Dates | date-fns | Manipulation de dates, léger et modulaire |
| Tables | @tanstack/react-table | Tableaux avec tri, filtre, pagination |
| Toast / Notifications | sonner | Notifications élégantes et simples |
| Drag & Drop | @dnd-kit/core | Drag and drop accessible et performant |
| Éditeurs de graphes | @xyflow/react (React Flow) | Éditeurs node-based interactifs (pipelines, workflows, diagrammes) |
| Icônes | lucide-react | +1000 icônes SVG en composants React |
@react-pdf/renderer | Générer des PDF avec des composants React | |
| Internationalisation | react-i18next | Traduction et localisation |
date-fns : l'utilitaire de dates
Ne réinventez jamais la manipulation de dates ! date-fns est léger et modulaire (vous n'importez que ce que vous utilisez).
import { format, addDays, isAfter } from 'date-fns';
import { fr } from 'date-fns/locale';
const today = new Date();
const nextWeek = addDays(today, 7);
format(today, 'dd MMMM yyyy', { locale: fr }); // "23 mars 2026"
isAfter(nextWeek, today); // true
Quelle est la différence principale entre shadcn/ui et une librairie de composants classique comme Material UI ?
Comment choisir une librairie ?
Face à un nouveau besoin, ne codez pas tout de zéro. Mais ne choisissez pas non plus la première librairie venue. Voici comment évaluer :
Les critères essentiels
-
Popularité et maintenance
- Nombre de stars GitHub et de téléchargements npm hebdomadaires
- Date du dernier commit (la librairie est-elle activement maintenue ?)
- Nombre d'issues ouvertes et de contributeurs
-
Taille du bundle
- Vérifiez sur bundlephobia.com la taille ajoutée à votre projet
- Une librairie de 200kb pour un problème simple ? Probablement excessif.
-
Qualité de la documentation
- Exemples clairs et à jour ?
- Guide de démarrage rapide ?
- Documentation de l'API complète ?
-
Compatibilité
- Supporte TypeScript ?
- Compatible avec votre version de React ?
- Fonctionne avec vos autres outils (Vite, Tailwind, etc.) ?
Les outils pour comparer
# Comparer les tendances de téléchargement
https://npmtrends.com/zustand-vs-jotai-vs-recoil
# Vérifier la taille d'un package
https://bundlephobia.com/package/zustand
# Explorer l'écosystème
https://github.com/enaqx/awesome-react
Le test des 50 lignes
Ai-je vraiment besoin d'une librairie ?
Avant d'installer une dépendance, posez-vous la question :
"Est-ce que je peux coder ça moi-même en moins de 50 lignes ?"
- ✅ Oui → Codez-le vous-même (fonction de formatage simple, petit hook utilitaire)
- ❌ Non → Utilisez une librairie battle-tested (formulaires, graphiques, 3D, drag & drop)
Par exemple :
- Formater une date en
JJ/MM/AAAA? Vous pouvez le faire en quelques lignes. - Gérer un formulaire complexe avec validation, erreurs par champ et performance ? Utilisez React Hook Form + Zod.
- Créer un graphique interactif ? Utilisez Recharts.
Récapitulatif
Ce que vous avez découvert
L'écosystème React — les bonnes briques pour chaque problème :
- Build : Vite (SPA) ou Next.js (fullstack/SSR)
- Routing : React Router DOM ou TanStack Router (type-safe)
- Validation : Zod, Yup, ou Valibot
- Formulaires : React Hook Form + Zod = combo parfait
- Data Fetching : TanStack Query (cache, refetch, invalidation)
- Graphiques : Recharts, Chart.js, Nivo
- 3D : React Three Fiber
- Animations : Framer Motion
- Composants UI : shadcn/ui (Radix + Tailwind)
- État global : Zustand
La démarche à retenir :
- ✅ Cherchez si une librairie existe avant de coder from scratch
- ✅ Évaluez : popularité, taille, docs, maintenance
- ✅ Utilisez le test des 50 lignes
- ✅ Lisez la documentation officielle
- ❌ N'installez pas une librairie de 200kb pour un problème de 10 lignes
React Hook Form
Formulaires performants avec validation intégrée
DocumentationTanStack Query
Data fetching avec cache, refetch et invalidation automatiques
DocumentationRecharts
Graphiques déclaratifs construits sur D3 et React
DocumentationReact Three Fiber
Scènes 3D avec Three.js et la syntaxe React
DocumentationFramer Motion
Animations déclaratives pour React
Documentationshadcn/ui
Composants accessibles et personnalisables (Radix + Tailwind)
DocumentationZustand
Gestion d'état globale simple et performante
Documentationnpm trends
Comparez la popularité des packages npm
DocumentationReact Flow
Éditeurs de graphes et workflows node-based interactifs
DocumentationBundlephobia
Vérifiez la taille d'un package avant de l'installer
DocumentationAwesome React
Liste curaturée de librairies et outils React
Documentation