React 19.2 : Activity Component et Partial Pre-rendering Changent Tout
Salut HaWkers, React 19.2 a été lancé en octobre 2025 et apporte des fonctionnalités qui changent fondamentalement la façon dont nous construisons des applications React. L'Activity component et le Partial Pre-rendering sont des game-changers.
Analysons chaque nouveauté et comment l'appliquer dans votre prochain projet.
L'Évolution de React 19
Depuis décembre 2024, React 19 a évolué rapidement. Voici la timeline :
Timeline des Lancements
Versions de React 19 :
| Version | Date | Points Forts |
|---|---|---|
| v19.0.0 | Décembre 2024 | Server Components, Actions |
| v19.1.0 | Mars 2025 | Améliorations de performance |
| v19.2.0 | Octobre 2025 | Activity, PPR, useEffectEvent |
React 19 complète la transition de React vers une architecture async-first, le plus grand changement depuis React Hooks.
Activity Component : Pre-rendering Intelligent
Qu'est-ce que Activity
Le composant Activity permet de pre-render et maintenir des parties cachées de l'application rendues sans impacter la performance de ce qui est visible.
Cas d'usage :
- Pre-render des routes : Pages que l'utilisateur va probablement accéder
- Préserver l'état : Maintenir l'état des parties naviguées
- Transitions fluides : Naviguer sans loading
- Optimisation UX : Expérience instantanée
Comment Ça Fonctionne
import { Activity } from 'react';
function App() {
const [currentTab, setCurrentTab] = useState('home');
return (
<div>
<TabBar current={currentTab} onChange={setCurrentTab} />
{/* Tab active - rendu normalement */}
<Activity mode={currentTab === 'home' ? 'visible' : 'hidden'}>
<HomeTab />
</Activity>
{/* Tab cachée - pre-rendue mais n'impacte pas la performance */}
<Activity mode={currentTab === 'profile' ? 'visible' : 'hidden'}>
<ProfileTab />
</Activity>
{/* Tab cachée - état préservé même quand non visible */}
<Activity mode={currentTab === 'settings' ? 'visible' : 'hidden'}>
<SettingsTab />
</Activity>
</div>
);
}Modes de Activity
Options disponibles :
| Mode | Comportement |
|---|---|
visible |
Rendu normalement, visible par l'utilisateur |
hidden |
Pre-rendu mais caché, état préservé |
Bénéfices de Performance
Comparaison de navigation :
// AVANT : Sans Activity - re-render à chaque navigation
function OldApp() {
const [tab, setTab] = useState('home');
// Chaque changement de tab détruit et recrée le composant
return (
<div>
{tab === 'home' && <HomeTab />}
{tab === 'profile' && <ProfileTab />}
</div>
);
}
// APRÈS : Avec Activity - état préservé
function NewApp() {
const [tab, setTab] = useState('home');
// Composants pre-rendus, navigation instantanée
return (
<div>
<Activity mode={tab === 'home' ? 'visible' : 'hidden'}>
<HomeTab />
</Activity>
<Activity mode={tab === 'profile' ? 'visible' : 'hidden'}>
<ProfileTab />
</Activity>
</div>
);
}
Partial Pre-rendering (PPR)
Qu'est-ce que PPR
Le Partial Pre-rendering permet de pre-render les parties statiques de l'application et de les servir depuis un CDN, en remplissant avec du contenu dynamique ensuite.
Le flux :
- Build time : Parties statiques pre-rendues
- CDN : Shell servi instantanément
- Runtime : Contenu dynamique remplit le shell
- Résultat : Time-to-first-byte minimum
Implémentation Pratique
// page.jsx - Partial Pre-rendering
import { Suspense } from 'react';
// Cette partie est pre-rendue au build
export default function ProductPage({ productId }) {
return (
<div>
{/* Header statique - pre-rendu */}
<Header />
<Navigation />
{/* Contenu dynamique - charge après */}
<Suspense fallback={<ProductSkeleton />}>
<ProductDetails productId={productId} />
</Suspense>
{/* Reviews dynamiques */}
<Suspense fallback={<ReviewsSkeleton />}>
<ProductReviews productId={productId} />
</Suspense>
{/* Footer statique - pre-rendu */}
<Footer />
</div>
);
}Gains de Performance
Métriques observées :
| Métrique | Sans PPR | Avec PPR | Amélioration |
|---|---|---|---|
| TTFB | 800ms | 50ms | 94% |
| LCP | 2.5s | 1.2s | 52% |
| FCP | 1.8s | 0.3s | 83% |
Partial Pre-rendering combine le meilleur du SSG et du SSR : vitesse du statique avec dynamisme du serveur.
useEffectEvent Hook
Le Problème Qu'il Résout
Avant useEffectEvent, gérer les callbacks dans les effects était problématique :
// AVANT : Problème avec les dépendances
function ChatRoom({ roomId, onMessage }) {
useEffect(() => {
const connection = createConnection(roomId);
connection.on('message', (msg) => {
// onMessage change à chaque render, causant une reconnexion
onMessage(msg);
});
return () => connection.close();
}, [roomId, onMessage]); // onMessage comme dépendance = problème
}La Solution Avec useEffectEvent
// APRÈS : useEffectEvent résout
import { useEffectEvent } from 'react';
function ChatRoom({ roomId, onMessage }) {
// Crée un event handler stable
const handleMessage = useEffectEvent((msg) => {
onMessage(msg);
});
useEffect(() => {
const connection = createConnection(roomId);
connection.on('message', handleMessage);
return () => connection.close();
}, [roomId]); // onMessage n'a pas besoin d'être une dépendance !
}Quand Utiliser
Cas d'usage idéaux :
- Event handlers dans effects : Callbacks qui ne doivent pas re-déclencher l'effect
- Analytics : Tracking qui a besoin de valeurs actuelles
- Notifications : Handlers qui changent mais ne doivent pas reconnecter
- WebSockets : Callbacks de message stables
// Exemple : Analytics sans re-trigger
function ProductPage({ product, analytics }) {
const trackView = useEffectEvent(() => {
// Utilise toujours l'analytics le plus récent
analytics.track('product_view', { id: product.id });
});
useEffect(() => {
trackView();
}, [product.id]); // analytics n'est pas une dépendance
}
cacheSignal API
Qu'est-ce que cacheSignal
L'API cacheSignal permet de créer des signaux de cache pour invalider les données de manière réactive.
import { cacheSignal, use } from 'react';
// Crée un signal de cache pour les produits
const productCache = cacheSignal();
async function fetchProduct(id) {
const response = await fetch(`/api/products/${id}`);
return response.json();
}
function ProductDetails({ productId }) {
// use() avec cache signal
const product = use(fetchProduct(productId), {
signal: productCache
});
return (
<div>
<h1>{product.name}</h1>
<p>{product.description}</p>
<button onClick={() => productCache.invalidate()}>
Recharger
</button>
</div>
);
}Invalidation Granulaire
// Invalider le cache spécifique
productCache.invalidate(); // Invalide tous les produits
// Invalider par clé
productCache.invalidate(productId); // Invalide un produit spécifique
// Invalider avec condition
productCache.invalidateIf((key) => key.startsWith('featured-'));
Performance Tracks
Debugging de Performance
React 19.2 a introduit les Performance Tracks pour un debugging avancé de la performance.
Ce qu'il montre :
- Render timing : Combien de temps chaque composant prend
- Suspense boundaries : Quand et pourquoi ils suspendent
- Transitions : Durée et états
- Effects : Timing des effects et cleanup
Comment Utiliser
// Activer Performance Tracks en dev
import { enableProfiler } from 'react-devtools';
enableProfiler({
tracks: true,
showSuspenseFallbacks: true,
highlightUpdates: true
});Intégration Avec DevTools
React DevTools 5.x :
- Visualisation des tracks dans le Profiler
- Timeline de Suspense
- Flamegraph amélioré
- Métriques de re-render
Migrer Vers React 19.2
Étape par Étape
1. Mettez à jour les dépendances :
npm install react@19.2.0 react-dom@19.2.02. Vérifiez la compatibilité :
// React 19.2 requiert :
// - Node.js 18+
// - Bundler moderne (Vite, webpack 5+)
// - TypeScript 5.0+ (si vous utilisez TS)3. Adoptez les fonctionnalités graduellement :
// Commencez avec Activity dans les zones de navigation
<Activity mode={isActive ? 'visible' : 'hidden'}>
<ExpensiveComponent />
</Activity>
// Ensuite ajoutez PPR sur les pages statiques
// En dernier, migrez les effects vers useEffectEventProblèmes Courants
Erreurs fréquentes :
| Erreur | Cause | Solution |
|---|---|---|
| Activity not defined | Import manquant | import { Activity } from 'react' |
| Hydration mismatch | Diff Server/Client | Vérifier les logs de diff |
| useEffectEvent in non-effect | Utilisation incorrecte | Utiliser uniquement pour effects |
React 19 vs Alternatives
Comparaison Avec les Frameworks
React 19.2 vs autres :
| Fonctionnalité | React 19.2 | Svelte 5 | Vue 3.5 | Solid 2 |
|---|---|---|---|---|
| Server Components | Oui | Partiel | Nuxt | Non |
| PPR | Oui | Non | Non | Non |
| Activity-like | Oui | Non | KeepAlive | Non |
| Signals | Via hooks | Natif | Natif | Natif |
Quand Choisir React 19
React 19.2 est idéal pour :
- Applications enterprise avec SSR
- Dashboards complexes avec beaucoup de tabs
- E-commerce avec PPR
- Apps nécessitant un état préservé
Le Futur de React
Roadmap 2026
Ce qu'il faut attendre :
- React Compiler GA : Optimisation automatique de memoization
- Plus d'APIs de cache : Invalidation encore plus granulaire
- Activity amélioré : Plus de modes et options
- DevTools AI : Suggestions d'optimisation
Impact sur le Marché
Tendances :
- React maintient sa position de leader
- Next.js comme principal framework
- Server Components comme standard
- Performance comme différenciateur
Conclusion
React 19.2 représente la maturité de la vision async-first de React. Activity component et Partial Pre-rendering résolvent des problèmes réels d'UX que les développeurs affrontent depuis des années.
Si vous n'avez pas encore migré vers React 19, c'est le moment. Les fonctionnalités de performance et DX justifient l'effort de mise à jour.
Pour en savoir plus sur l'écosystème JavaScript en 2025, je recommande de consulter l'article sur TypeScript Dépasse Python où nous analysons les langages les plus utilisés.
C'est parti ! 🦅
💻 Maîtrisez JavaScript Pour Maîtriser React
React est construit sur JavaScript. Maîtriser les fondamentaux est essentiel pour profiter pleinement des nouvelles fonctionnalités.
Matériel Complet
J'ai préparé un guide qui va du niveau débutant à avancé :
Investissement :
- 1x de 9,90€ par carte
- ou 9,90€ comptant

