React 19.2 : Toutes les nouveautés qui vont changer ta façon de coder
05/10/2025 • Melvynx
05/10/2025 • Melvynx
React 19.2 est sorti le 1er octobre 2025 et il apporte des nouveautés vraiment importantes qui vont changer ta façon de coder.
Je vais t'expliquer toutes les nouveautés principales avec des exemples concrets pour que tu puisses les utiliser dès aujourd'hui dans tes projets.
<Activity>
: Le composant qui change toutLe composant <Activity>
est pour moi LA nouveauté majeure de React 19.2. Il permet de cacher un composant sans détruire son état.
Avant, quand tu faisais ça :
function Tabs() {
const [tab, setTab] = useState('home');
return (
<>
<button onClick={() => setTab('home')}>Accueil</button>
<button onClick={() => setTab('contact')}>Contact</button>
{tab === 'home' && <HomePage />}
{tab === 'contact' && <ContactForm />}
</>
);
}
Le problème c'est que quand tu changes d'onglet, tout l'état est perdu. Si tu as rempli un formulaire dans ContactForm
et que tu reviens sur HomePage
, quand tu retournes sur Contact
, ton formulaire est vide.
<Activity>
Maintenant avec <Activity>
, tu peux faire ça :
import { Activity } from 'react';
function Tabs() {
const [tab, setTab] = useState('home');
return (
<>
<button onClick={() => setTab('home')}>Accueil</button>
<button onClick={() => setTab('contact')}>Contact</button>
<Activity mode={tab === 'home' ? 'visible' : 'hidden'}>
<HomePage />
</Activity>
<Activity mode={tab === 'contact' ? 'visible' : 'hidden'}>
<ContactForm /> {/* L'état du formulaire est préservé ! */}
</Activity>
</>
);
}
Et voilà ! Ton formulaire garde son état même quand tu changes d'onglet.
Voici un exemple plus concret avec un lecteur vidéo :
Tu peux tester : change d'onglet, le temps et l'état de lecture sont conservés !
Quand tu utilises mode="hidden"
:
C'est parfait pour :
useEffectEvent
: Fini les dépendances infiniesATTENTION : Il n'y a PAS de hook useEvent
dans React 19.2. Le vrai nom c'est useEffectEvent
et il est encore expérimental.
Tu as sûrement déjà eu ce problème :
function ChatRoom({ roomId, theme }) {
useEffect(() => {
const connection = createConnection(roomId);
connection.on('connected', () => {
showNotification('Connecté!', theme); // On utilise theme
});
connection.connect();
return () => connection.disconnect();
}, [roomId, theme]); // ❌ On doit ajouter theme, mais ça reconnecte !
}
Le problème c'est que chaque fois que theme
change, on reconnecte. C'est nul !
useEffectEvent
import { useEffectEvent } from 'react';
function ChatRoom({ roomId, theme }) {
// On extrait la logique non-réactive
const onConnected = useEffectEvent(() => {
showNotification('Connecté!', theme); // theme est toujours à jour
});
useEffect(() => {
const connection = createConnection(roomId);
connection.on('connected', () => {
onConnected(); // On appelle l'event
});
connection.connect();
return () => connection.disconnect();
}, [roomId]); // ✅ On ne reconnecte que si roomId change !
}
Maintenant, theme
peut changer autant qu'il veut, on ne reconnecte que si roomId
change.
Voici un exemple très concret pour du tracking :
Ouvre la console et teste : tu vas voir la différence !
React 19.2 ajoute des pistes de performance dans Chrome DevTools qui te permettent de voir exactement ce qui se passe dans ton application.
F12
)Tu vas voir deux nouvelles pistes :
Cette piste te montre les différentes priorités de React :
Cette piste te montre pour chaque composant :
Tu peux aussi utiliser le composant Profiler
:
import { Profiler } from 'react';
function App() {
return (
<Profiler id="App" onRender={onRenderCallback}>
<YourApp />
</Profiler>
);
}
function onRenderCallback(id, phase, actualDuration) {
console.log(`${id} rendu en ${actualDuration}ms`);
}
C'est vraiment puissant pour optimiser tes performances !
React 19.2 introduit le Partial Pre-rendering (PPR) qui permet de pré-rendre des parties statiques de ta page et de "reprendre" le rendu plus tard avec les parties dynamiques.
import { prerender } from 'react-dom/static';
import { resume } from 'react-dom/server';
// ÉTAPE 1: Pré-rendre le shell statique
const { prelude, postponed } = await prerender(<App />);
// Envoyer le HTML statique au client
sendToClient(prelude);
// ÉTAPE 2: Reprendre avec les données dynamiques
const resumeStream = await resume(<App />, postponed);
sendStreamToClient(resumeStream);
C'est parfait pour :
cacheSignal
: Annuler les requêtes inutilesLe cacheSignal
est un nouvel API uniquement pour les Server Components qui permet d'annuler automatiquement les requêtes quand elles ne sont plus nécessaires.
import { cache, cacheSignal } from 'react';
const fetchUser = cache(fetch);
async function UserProfile({ userId }) {
// La requête s'annule automatiquement si le rendu est abandonné
const userData = await fetchUser(
`https://api.example.com/users/${userId}`,
{ signal: cacheSignal() }
);
return <div>{userData.name}</div>;
}
C'est super utile pour éviter les requêtes inutiles quand tu navigues rapidement.
Avant, les Suspense
boundaries se révélaient une par une, ce qui créait des "flash" désagréables.
Maintenant, React 19.2 groupe les révélations pour afficher plusieurs boundaries en même temps :
function ProductPage() {
return (
<div>
<Suspense fallback={<LoadingHeader />}>
<Header />
</Suspense>
<Suspense fallback={<LoadingProduct />}>
<ProductDetails />
</Suspense>
<Suspense fallback={<LoadingReviews />}>
<Reviews />
</Suspense>
{/* React attend un peu pour révéler plusieurs boundaries ensemble */}
</div>
);
}
Résultat : une expérience plus fluide pour l'utilisateur !
Pour migrer, c'est simple :
npm install react@19.2 react-dom@19.2
# Met à jour ESLint
npm install eslint-plugin-react-hooks@6.1.1
Points importants :
<Activity>
est stable et prêt pour la produseEffectEvent
est expérimental (peut changer)cacheSignal
fonctionne uniquement avec les Server ComponentsD'après les benchmarks officiels :
C'est vraiment impressionnant !
React 19.2 est une mise à jour majeure qui apporte :
<Activity>
pour gérer l'état des composants cachésuseEffectEvent
pour simplifier les effectsSi tu veux maîtriser React et toutes ces nouveautés, je te recommande ma formation gratuite :