Accueil / Articles

Pourquoi le développement frontend est difficile après React : l’état, les effets, les limites et les outils d’IA

React a rendu la création d’interfaces utilisateur plus simple, mais pas leur conception. Là où se trouve l’état, ce sont les effets complexes, les limites du système et le code généré par l’IA qui représentent le véritable travail côté frontend.

Éditeur : REACTAPP.TOP9 min de lecture2114 mots

Sources: React Isn’t the Hardest Part of Frontend Development

Certains développeurs frontend parviennent à créer un composant React en vingt minutes, puis passent les trois heures suivantes à essayer de comprendre pourquoi il devient ensuite impossible à maintenir. La cause n’est pas JSX, ni useState, et ce n’est pas vraiment React non plus. Ce qui rend le travail frontend difficile, c’est tout ce qui entoure le framework : savoir comment un produit doit se comporter, choisir où stocker l’état, coordonner les appels asynchrones, définir les limites des composants, gérer les particularités du navigateur, assurer que les interfaces restent accessibles et rapides, et laisser un code qui reste compréhensible même six mois plus tard.

React a rendu la création d’interfaces plus simple. Il n’a jamais rendu l’ingénierie frontend facile, et ce domaine a trop longtemps fait semblant que c’était le cas.

Ce que React a corrigé, et ce qu’il a laissé en l’état

Au moment où React n’existait pas encore, les difficultés étaient d’un autre ordre. Les développeurs modifiaient manuellement le DOM et connectaient les gestionnaires d’événements un par un, et ils avaient du mal à maintenir l’écran en synchronisation avec les données de l’application. À mesure que les applications grandissaient, il devenait de plus en plus difficile de suivre les relations entre les actions de l’utilisateur, les données et les éléments affichés.

React a proposé un modèle mental utile : l’interface utilisateur est une fonction de l’état. Au lieu d’indiquer au navigateur chaque modification du DOM, on décrit à quoi ressemble l’interface pour un état donné. Les composants définissent les limites, les props fournissent des entrées explicites, l’état représente les données qui évoluent dans le temps, et le rendu déclaratif élimine une grande partie de la complexité accidentelle. C’était un véritable progrès.

Néanmoins, un framework ne résout que ce pour quoi il a été conçu. React n’a aucune opinion sur le fait qu’une application ait besoin de cinq ou de cinquante éléments d’état global. Il ne peut pas indiquer quand un composant fait trop de choses, si la conception de votre API est judicieuse, si les indicateurs de chargement se trouvent aux bons endroits, ou si le flux de paiement est logique pour l’acheteur. De plus, il ne peut certainement pas décider de ce que le produit doit faire en cas de perte de connexion au milieu d’une requête. Tous ces problèmes relèvent également du front-end.

Une fonctionnalité ordinaire face à la réalité

Prenons un tableau de bord simple. Un utilisateur l’ouvre, l’application récupère des données, il modifie un filtre, les résultats se mettent à jour, il sélectionne un élément, un modal s’ouvre, il modifie et enregistre, le serveur répond et le tableau de bord se met à jour. Rien dans tout cela ne semble difficile.

Voici ce qui se passe réellement. La première requête échoue. Le filtre change alors qu’une requête précédente est encore en cours d’exécution, et la réponse ancienne arrive après la nouvelle. Le modal s’ouvre à partir d’un lien profond. La page est mise à jour au milieu d’une modification. Deux onglets sont ouverts. La session expire. L’API renvoie des données partielles. Le serveur accepte une mutation mais le client ne voit jamais la réponse, et l’utilisateur clique sur enregistrer deux fois. La liste compte 10 000 lignes, la connexion est lente et via un appareil mobile, l’interface doit fonctionner avec un clavier, et le message d’erreur doit indiquer aux utilisateurs ce qu’ils peuvent faire ensuite.

À ce stade, le code React est la partie la moins intéressante. Tout cela peut être développé avec React, et tout cela peut également être mal implémenté. De nombreux développeurs manquent cette différence.

La tâche consiste à gérer la complexité

Le travail d’un développeur frontend ne consiste pas principalement à écrire des composants. Il s’agit plutôt d’absorber la complexité afin que l’utilisateur voie quelque chose de simple, ce qui est bien plus difficile. Un composant bien conçu peut compter cinquante lignes de code, mais atteindre ce chiffre plutôt que cinq cents exige une série de décisions :

  • D’où proviennent les données, qui en est le propriétaire, combien de temps elles restent en mémoire et qui peut les modifier
  • Que se passe-t-il lorsque une requête échoue
  • Si l’état doit être conservé après une navigation ou un rechargement
  • Si cet état doit figurer dans l’URL, dans l’état local du composant ou dans un cache serveur
  • Si deux composants doivent partager les données elles-mêmes ou simplement calculer des valeurs similaires de leur propre chef

React ne répond à aucune de ces questions. C’est le développeur qui le fait, et les réponses s’accumulent. Une décision faible reste rarement confinée à un seul composant : elle se transforme en modèle que d’autres développeurs copient, et bientôt l’application dispose d’une architecture cohérente que personne n’a choisie. C’est ainsi que les bases de code frontend deviennent complexes : les décisions s’accumulent, et la complexité de React n’y est que peu pour quelque chose.

La state en tant que problème de modélisation

Un moyen rapide de détecter un design frontend immature est d’examiner sa state. Une utilisation intensive de useState n’est pas en soi une erreur. Le problème réside dans le fait de considérer la state comme un simple endroit pour stocker des valeurs plutôt que comme quelque chose à modéliser. Lorsqu’un développeur voit une valeur qui change, il a tendance à utiliser le hook correspondant.

const [value, setValue] = useState(...)

Cela semble terminé, mais la vraie question n’est pas de savoir comment stocker la valeur. La vraie question est de savoir si cette valeur doit exister du tout. Regardez ce trio :

const [firstName, setFirstName] = useState("");
const [lastName, setLastName] = useState("");
const [fullName, setFullName] = useState("");

Trois composants de l’application contiennent actuellement des informations qui pourraient être obtenues à partir de deux seulement. Ce n’est pas React qui en est responsable ; c’est le modèle mental utilisé.

La même chose se produit à grande échelle. Les équipes conservent les réponses API, des copies filtrées de ces réponses, des indicateurs de chargement, des comptages dérivés, les enregistrements sélectionnés, des indicateurs de modaux ainsi que des versions dupliquées d’une même entité en plusieurs endroits. Avec le temps, personne ne sait plus quelle copie est la plus fiable, ce qui entraîne des bugs. Un composant modifie une copie tandis qu’un autre en lit une différente. Un effet de synchronisation tente de les aligner, tandis qu’un autre effet réagit au premier. Soudain, le navigateur devient un petit système distribué. Ce n’est pas React qui a conçu cette architecture, mais bien les personnes qui écrivent le code.

Les effets révèlent la conception

Si une fonctionnalité de React est plus souvent critiquée que les autres, c’est useEffect, et ces critiques sont souvent justifiées. Cependant, c’est généralement là que se manifeste un problème d’architecture, et non là où il commence.

Imaginez un composant contenant plusieurs effets : un pour récupérer des données, un pour synchroniser l’état, un pour réagir à un changement de propriété, un pour écrire dans le stockage local, un pour envoyer des données d’analyse, et un pour réinitialiser quelque chose lorsque la condition change. Chacun semble raisonnable pris individuellement. Ensemble, ils forment un graphe de dépendances difficile à suivre. Le développeur ajoute des dépendances jusqu’à ce que l’outil de vérification se taise, ou en supprime certaines parce que l’effet s’exécute trop souvent, ou ajoute un référent booléen pour éviter une exécution double. Finalement, le composant fonctionne pour le scénario testé, sans que personne ne sache vraiment pourquoi.

Ce n’est pas une faille de React. Il s’agit plutôt d’une responsabilité floue et d’effets secondaires emmêlés, et React fournit simplement un endroit où les placer.

Le navigateur n’est qu’un nœud au sein d’un système bien plus vaste

Les tâches liées à l’interface utilisateur s’élargissent constamment. Une application moderne interagit avec des API et des bases de données, des systèmes d’authentification et des outils d’analyse, ainsi qu’avec des fonctionnalités conditionnelles, des fournisseurs de paiement et d’autres services tiers. S’y ajoutent des fonctions d’edge, des composants serveur, des tâches en arrière-plan, et de plus en plus, des services basés sur l’IA. Le navigateur n’est donc qu’un des acteurs d’un système bien plus grand, ce qui oblige les développeurs d’interface utilisateur à maîtriser bien plus que simplement le rendu, y compris ce qui se passe avant et après que une requête quitte la page.

Cela ne signifie pas que tout le monde doit devenir spécialiste du backend. Cela veut dire que la distinction traditionnelle entre frontend et backend devient de moins en moins utile. Une personne qui ne connaît pas HTTP aura tôt ou tard des difficultés avec le caching. Celui qui n’est pas familier avec les bases de données aura du mal à comprendre les concepts de cohérence, et celui qui ne maîtrise pas l’authentification se heurtera au comportement des sessions. Les conditions de concurrence et les tentatives de réessai déconcertent les développeurs sans expérience en systèmes distribués, et ceux qui ne comprennent pas les utilisateurs créent des interfaces élégantes que personne n’apprécie. Le framework représente une seule couche.

L’IA change la logistique économique, pas la partie technique difficile

Les assistants de codage basés sur l’IA ont modifié le coût des tâches front-end. La création de composants, de formulaires, de conversions design en JSX, d’hooks et de tests devient moins coûteuse. Cela peut sembler menaçant. Il vaut mieux y voir un test pour déterminer où résidait réellement la valeur. Si votre principale contribution consiste à taper rapidement du JSX, l’IA représente un problème. Si elle repose plutôt sur une compréhension des systèmes, de l’architecture, du comportement du produit, des compromis à faire et des utilisateurs, l’IA modifie votre flux de travail tout en laissant en place les parties difficiles, voire en en augmentant l’importance.

Un assistant peut rédiger en quelques secondes trois versions plausibles d’une fonctionnalité. Le choix parmi elles relève de la décision architecturale et non de la syntaxe. Il peut concevoir un système de gestion d’état, mais cet état doit-il être global ? Il peut écrire une mise à jour optimiste, mais l’application doit-elle vraiment se comporter de manière optimiste ? Il peut ajouter un cache, mais quelle est la stratégie d’invalidation ? Il peut écrire un effet, mais cet effet doit-il exister ? Plus le code apparaît rapidement, plus le jugement est nécessaire, et c’est probablement ce qui définira le travail frontend au cours des prochaines années.

Les développeurs front-end compétents ont tendance à se concentrer moins sur React et davantage sur les limites de fonctionnement. Ils se demandent où réside la responsabilité et remarquent quand un composant devient une petite application. Ils luttent contre la duplication des états, planifient les échecs avant même le scénario idéal, connaissent précisément ce que l’API garantit et prêtent attention au comportement inattendu des utilisateurs. Ils savent quand une abstraction est utile et quand elle ne fait que cacher la complexité. Ils comprennent le navigateur, ajustent les performances sans optimiser tout de suite, et, surtout, peuvent expliquer pourquoi le système fonctionne de cette manière. C’est une compétence bien plus difficile à automatiser, et elle dure plus longtemps que la maîtrise de la dernière API React.

Les connaissances sur les frameworks s’érodent

Les développeurs n’en parlent pas assez : les connaissances relatives aux frameworks ont une durée de validité limitée. L’API de React apprise il y a cinq ans n’est plus tout à fait celle d’aujourd’hui. Les meilleures pratiques évoluent, les bibliothèques disparaissent, les outils de construction changent, les stratégies de rendu se développent, les capacités serveur s’améliorent et de nouveaux frameworks voient le jour. La syntaxe évolue, mais les problèmes d’ingénierie fondamentaux restent remarquablement stables :

  • Modélisation de l’état et transmission des données au sein d’un système
  • Gestion des pannes et traitement des tâches asynchrones
  • Évitement d’un couplage inutile
  • Rendre un système observable et une interface accessible
  • Contrôle de la complexité

Ces problèmes ont survécu à jQuery, Angular et Backbone, ainsi qu’au début de l’écosystème React. Ils survivront à tout ce qui viendra par la suite. Ainsi, apprendre le développement frontend uniquement à travers les frameworks est une approche fragile. Apprenez le framework, mais ne le confondez pas avec la discipline requise.

React pourrait un jour cesser d’être au centre des discussions. Quelque chose pourrait le remplacer, plusieurs approches pourraient coexister, ou il pourrait rester dominant bien plus longtemps que prévu. Cela n’a pas vraiment d’importance. Les développeurs dont l’identité repose sur les API de React devront les reconstruire, tandis que ceux qui ont appris comment fonctionnent réellement les interfaces s’adapteront.

React est un outil, pas une compétence

Le développement frontend n’a jamais été fondamentalement lié à React. React est un outil très efficace pour créer des applications frontend, et il reste un outil. La partie difficile consiste à décider de ce qu’il faut exprimer : comment les éléments interagissent, ce qui se passe lorsque quelque chose ne fonctionne pas, où se trouve l’état, ce qui s’exécute dans le navigateur par rapport au serveur, comment le système évolue avec le produit, et comment cacher tout cela à l’utilisateur. C’est là la tâche, et JSX n’est qu’un moyen de saisir certaines parties de celle-ci.

À mesure que les outils deviennent plus performants pour générer du code, sa création prend de moins en moins de valeur. Cela ne met pas fin au développement logiciel, mais cela change ce sur quoi les développeurs doivent se concentrer dans leur travail. Celui qui peut générer rapidement un composant est utile, mais celui qui sait juger s’il doit exister l’est encore plus. Il en va de même pour les intégrations API : en générer une est utile, mais détecter que le contrat lui-même est incorrect a encore plus de valeur. Un développeur capable de demander à l’IA de refactorer une base de code a de la valeur, et celui qui peut déterminer si le refacteur proposé améliore le système en a encore plus.

Ainsi, personne ne devrait s’inquiéter du fait que React devienne plus simple. C’est justement l’objectif, car la fonction d’un framework est de réduire le travail inutile, et un développeur expérimenté utilise le temps gagné pour s’attaquer aux problèmes importants.

Lectures complémentaires

  • Tester GLM 5.2 dans Claude Code à l’aide d’un SDK réel pour cinq dollars — Une expérience OpenRouter à cinq dollars : diriger Claude Code vers GLM 5.2, auditer et modifier un SDK React Native, le coût de chaque tâche, et là où les économies s’arrêtent.
  • Ajouter un écran de chargement à une application React Native sur iOS et Android — Configuration étape par étape d’un écran de chargement pour React Native sur iOS et Android : écran de démarrage d’Xcode, thèmes et layouts Android, ainsi que react-native-splash-screen pour éviter l’éclairage blanc.
  • React continue de dominer, mais le développement en JavaScript évolue — React reste en tête en termes d’utilisation, mais les approches associées incluent désormais TypeScript, le rendu serveur, des outils de compilation, des améliorations de performance et l’intelligence artificielle. Voici ce qu’il convient d’apprendre ensuite.
  • 30 astuces React et Redux pour des interfaces utilisateur évolutives et faciles à maintenir — Trente conseils courts sur React et Redux concernant l’état, les données serveur, les hooks, les sélecteurs, la structure des dossiers, les tests et le refactoring, destinés aux applications qui dépassent le millier de composants.