React, c’est génial pour démarrer vite, créer des interfaces modernes et faire plaisir aux utilisateurs.
Mais après quelques mois, puis quelques années, la vraie question devient :
Est-ce qu’on pourra encore comprendre ce code… sans avoir envie de tout réécrire ?
La bonne nouvelle : oui, si on pose dès le départ quelques bonnes pratiques de structure, de style et d’organisation.
Voici les principaux piliers pour garder un projet React lisible, stable et évolutif dans le temps.
1️⃣ Définir une architecture claire… et s’y tenir
Le plus gros risque avec React, c’est de « jeter » les fichiers là où ça passe, en mode freestyle.
Résultat au bout d’un moment : /components devient une brocante.
Quelques principes simples :
-
Séparer par domaines métier, pas juste par types de fichiers
Par exemple :-
features/users/ -
features/orders/ -
features/auth/
plutôt que -
components/ -
pages/ -
utils/
-
-
Organiser chaque feature avec une mini-structure :
-
components/(UI locale à la feature) -
hooks/ -
services/(API) -
types/ -
store/(si gestion d’état locale)
-
-
Limiter le “fourre-tout”
Si un dossier commence à devenir un sac de sport, c’est le moment de découper.
👉 Une architecture claire, c’est ce qui permet à quelqu’un d’arriver dans le projet dans 6 mois… sans paniquer.
2️⃣ Adopter une convention de code et l’automatiser
Pas de maintenance sereine sans cohérence de style.
Ce n’est pas pour faire joli : c’est ce qui évite les micro-pertes de temps 50 fois par jour.
À mettre en place dès le début :
-
Prettier pour le formatage automatique (espaces, guillemets, etc.).
-
ESLint avec des règles adaptées à React (et TypeScript si utilisé).
-
Un fichier de config partagé dans le repo (
.eslintrc,.prettierrc) -
Un pre-commit hook (via Husky par ex.) pour formater et lint avant chaque commit.
Résultat :
-
Un code qui se ressemble partout.
-
Des PR plus lisibles (on ne commente plus sur les espaces ou les virgules).
-
Moins de bugs idiots (variables non utilisées, imports oubliés, etc.).
3️⃣ Typage : dire adieu aux surprises avec TypeScript (ou PropTypes a minima)
Sur un petit projet, on se dit souvent :
« On verra plus tard pour TypeScript »
Le problème, c’est que “plus tard” n’arrive jamais… et qu’au bout d’un moment, on ne sait plus exactement ce que chaque fonction est censée recevoir.
Solutions possibles :
-
Idéal : TypeScript dès le départ
-
Types et interfaces clairs pour les props, les réponses API, les hooks, etc.
-
Autocomplétion + sécurité pendant l’édition.
-
Moins de bugs au runtime.
-
-
Minimum vital : PropTypes
-
Vérifier les types au runtime côté dev.
-
Documenter les props des composants.
-
👉 Le typage, c’est ce qui évite d’avoir peur chaque fois qu’on touche à un composant vieux de 18 mois.
4️⃣ Bien gérer l’état : ne pas tout mettre dans le global
Un classique : tout mettre dans Redux ou dans un contexte global « au cas où ».
Résultat : un état global tentaculaire, difficile à tester, à migrer ou à faire évoluer.
Quelques bonnes pratiques :
-
État local par défaut
-
Si une info n’est utilisée que dans un composant ou une petite branche, elle reste locale (
useState,useReducer).
-
-
Contexte ou store global seulement pour :
-
authentification,
-
préférences utilisateur,
-
données partagées entre de nombreux écrans.
-
-
Choisir des outils modernes :
-
Redux Toolkit (plus simple que Redux “vanilla”),
-
Zustand, Jotai, Recoil,
-
ou parfois un simple
Context + useReducerbien structuré.
-
-
Ne pas dupliquer l’état
-
Si une donnée vient de l’API, éviter de la re-stocker dans 3 stores différents.
-
👉 Un état bien pensé, c’est l’assurance de ne pas casser tout le site dès qu’on modifie un flux métier.
5️⃣ Découper les composants : petits, lisibles et réutilisables
Les composants “Godzilla” de 600 lignes, ça marche… jusqu’au jour où il faut y toucher.
Bon réflexe :
-
Un composant = une responsabilité principale
-
Un composant d’affichage,
-
Un composant “container” pour la logique,
-
Éventuellement un composant de layout.
-
-
Utiliser des hooks personnalisés (
useXXX) pour :-
la logique métier (chargement de données, filtrage, etc.),
-
la logique d’UI (ouverture/fermeture de modale, gestion de formulaires, etc.).
-
Exemple :
-
useUserList()gère les appels API, les erreurs, le loading. -
UserListne fait que rendre des composants en fonction de cet état.
👉 Au final : des composants courts, testables, réutilisables, et beaucoup moins effrayants.
6️⃣ Tester ce qui compte (sans tomber dans l’extrême inverse)
Pas besoin de 100 % de couverture au début.
Mais une absence totale de tests, c’est le ticket d’entrée pour l’angoisse de chaque refactor.
Ce qui est vraiment utile à tester :
-
La logique des hooks personnalisés :
-
gestion des états
loading,success,error -
traitement des données,
-
-
Les composants critiques (formulaires importants, étapes de commande, etc.),
-
Les règles métier clés (validation, calculs, etc.).
Outils fréquents :
-
Jest pour les tests unitaires,
-
React Testing Library pour les composants,
-
éventuellement Cypress / Playwright pour les tests E2E sur les parcours critiques.
👉 L’idée n’est pas de tester chaque pixel, mais de sécuriser ce qui casserait le business si ça bug.
7️⃣ Documenter les décisions… pas seulement le code
Un projet React qui dure, c’est aussi un projet où l’on sait pourquoi certaines décisions ont été prises.
Idées simples à mettre en place :
-
Un fichier
ARCHITECTURE.mdà la racine du projet, pour expliquer :-
comment les features sont organisées,
-
où se trouve la gestion d’état,
-
comment sont structurés les appels API,
-
quelles conventions de nommage sont en place.
-
-
Des
README.mddans les dossiers de features importantes. -
Une documentation fonctionnelle légère (ex : Notion, Confluence) qui explique :
-
les grandes règles métier,
-
les rôles des principaux écrans.
-
👉 La doc n’a pas besoin d’être parfaite, elle doit être utile, surtout pour quelqu’un qui arrive après.
8️⃣ Gérer proprement les dépendances et les mises à jour
Un projet React qui dure, c’est un projet qui n’accumule pas 4 ans de retard de dépendances.
Bonnes habitudes :
-
Éviter les librairies exotiques pour des cas simples (carrousel, modale, bouton…).
-
Préférer quelques dépendances solides, maintenues et reconnues.
-
Planifier régulièrement :
-
un check des dépendances (
npm outdated/yarn outdated), -
une mise à jour des versions mineures/patch,
-
un créneau pour migrer vers les versions majeures.
-
👉 Mieux vaut des petites mises à jour régulières que une énorme migration douloureuse tous les 5 ans.
9️⃣ Automatiser ce qui peut l’être : CI, builds, tests
Pour maintenir un projet dans le temps, l’automatisation est ton meilleur allié.
À prévoir :
-
Une intégration continue (CI) qui :
-
lance les tests,
-
exécute le lint,
-
vérifie que le build passe.
-
-
Des environnements distincts :
-
dev / recette / préprod / prod,
-
pour tester avant de déployer en réel.
-
👉 Ça évite les “Oups, j’ai cassé la prod” un vendredi à 17h.
🔟 Être réaliste : mieux vaut simple et clair que “trop clever”
Dernier point, mais peut-être le plus important :
Le code sera relu un jour par quelqu’un d’autre (ou par toi dans 1 an).
Mieux vaut qu’il soit simple à comprendre plutôt que “brillant”.
-
Éviter les patterns compliqués “juste pour le plaisir”,
-
Privilégier la clarté à la magie,
-
Commenter les morceaux un peu tordus (ou les simplifier).
👉 Si un composant ou un hook nécessite un schéma pour être compris, c’est peut-être qu’il est trop complexe.
🎯 En résumé : la longévité d’un projet React, c’est un choix dès le départ
Pour maintenir un projet React dans la durée, il faut :
-
une architecture claire et stable,
-
un style de code cohérent (ESLint + Prettier),
-
du typage (TypeScript ou PropTypes),
-
une gestion d’état réfléchie,
-
des composants découpés et testables,
-
des tests ciblés sur ce qui compte,
-
une documentation utile,
-
des dépendances maîtrisées,
-
une automation minimale (CI, builds, tests).
Ce n’est pas de la théorie : c’est ce qui fait la différence entre
un projet qu’on peut encore faire évoluer tranquillement après 3 ans…
et un projet qu’on veut réécrire dès que possible.