React 18 marque un tournant majeur dans l'écosystème React avec l'introduction du Concurrent Rendering et des Server Components. Ce guide pratique vous accompagne pas à pas dans la migration de vos projets.
Roadmap d'adoption

Étape 1 : Préparation
Mise à jour technique
Commencez par mettre à jour les dépendances :
npm install react@18 react-dom@18
Adaptez votre point d'entrée :
// Nouveau Root API
import { createRoot } from 'react-dom/client';
const root = createRoot(document.getElementById('root'));
root.render(<App />);
Étape 2 : Concurrent Mode
Automatic Batching
Regroupement automatique des mises à jour d'état :
// Avant : multiples re-renders
setState1(...);
setState2(...);
// Après : batch automatique
function handleClick() {
setState1(...); // Un seul re-render
setState2(...);
}
Transitions API
Priorisation des mises à jour :
import { startTransition } from 'react';
// Urgent : mise à jour immédiate
setInputValue(input);
// Non urgent : peut être interrompu
startTransition(() => {
setSearchQuery(input);
});
Étape 3 : Server Components
Structure recommandée
/components
/client # Composants clients
/server # Composants serveurs
Exemple de Server Component :
// app/server/Product.server.jsx
async function Product({ id }) {
const data = await fetchProduct(id); // Exécuté côté serveur
return <ProductDetail data={data} />;
}
Comparaison des performances
Métrique | React 17 | React 18 |
---|---|---|
TTI (Time to Interactive) | 2.1s | 1.4s |
Taille du bundle | 145kB | 98kB |
FCP (First Contentful Paint) | 1.8s | 1.2s |
Migration d'un composant
Avant (React 17) :
class UserProfile extends React.Component {
state = { loading: true };
componentDidMount() {
fetchUser().then(user => {
this.setState({ user, loading: false });
});
}
render() {
if (this.state.loading) return <Spinner />;
return <Profile data={this.state.user} />;
}
}
Après (React 18) :
function UserProfile() {
const [user, setUser] = useState(null);
useEffect(() => {
startTransition(() => {
fetchUser().then(setUser);
});
}, []);
return (
<Suspense fallback={<Spinner />}>
{user ? <Profile data={user} /> : null}
</Suspense>
);
}
Retour au blog