Mike Codeur Formations
Se connecter
Mike Codeur Formations

By Mike Codeur

© 2026 Mike Codeur Formations. Tous droits réservés.

Produit

  • Formations
  • Documentation
  • Blog

Légal & Contact

  • Mentions légales
  • Politique de confidentialité
  • Contact
Commencer

Prêt à commencer ?

Rejoignez des milliers d'utilisateurs qui créent des choses incroyables avec notre plateforme.

Commencer gratuitement

Pas de carte de crédit requise

Newsletter

Restez informé de nos derniers articles et actualités du développement web.

Pas de spam, désabonnement à tout moment

Retour aux articlesTutorial

Le Proxy Component en React

Un pattern simple pour isoler vos composants du changement : centraliser une implémentation au lieu de la dupliquer partout dans votre code.

#react#patterns#components
Mike Codeur
01 août 20266 min
Tutorial
…
Écrit par
MC
Mike Codeur
Auteur
Publié le 01 août 2026

Articles connexes

Introduction à Next.js 16Development

Introduction à Next.js 16

Ce qui change concrètement quand on développe avec Next.js 16 et React 19 : params asynchrones, Server Components, Server Actions et Turbopack.

03 août 20265 min
Lire la suite
Design
Design

Tailwind CSS v4 : la configuration passe dans le CSS

Fini le tailwind.config.js. La v4 déplace toute la configuration dans votre feuille de style, avec @theme, @plugin et @custom-variant.

02 août 20265 min
Lire la suite
Derrière ce nom un peu barbare se cache une idée toute simple, et probablement le pattern React qui vous fera gagner le plus de temps sur la durée : ne jamais laisser une implémentation se répandre dans votre code. Un Proxy Component est un composant qui n'existe que pour en envelopper un autre. Il ne fait presque rien. Et c'est précisément pour ça qu'il est utile.

Le problème

Prenons une application avec des boutons « Like » un peu partout :
function Header() {
  return (
    <div>
      <h1>Bienvenue</h1>
      <button>Like</button>
    </div>
  )
}

function Content() {
  return (
    <div>
      <h2>Articles</h2>
      <span>Article 1</span>
      <button>Like</button>
      <span>Article 2</span>
      <button>Like</button>
    </div>
  )
}

function Footer() {
  return (
    <div>
      <h3>Nous contacter</h3>
      <button>Like</button>
    </div>
  )
}
Tout va bien. Jusqu'au jour où il faut changer l'implémentation du bouton — passer à la librairie de composants de l'entreprise, ajouter une classe, brancher un tracking analytics :
// avant
<button>Like</button>

// après
<Button variant="ghost" size="sm" onClick={track}>Like</Button>
Vous voilà parti pour un rechercher-remplacer dans tout le projet. Sur cinq occurrences, ça passe. Sur cent-cinquante, réparties dans quarante fichiers, c'est une journée perdue — et une occasion d'en oublier trois.
Le vrai coût n'est pas le nombre de lignes à changer, c'est le risque. Chaque occurrence oubliée devient une incohérence visuelle que personne ne verra avant la production.

La solution

Créez un composant qui ne fait que déléguer :
function LikeButton(props) {
  return <button {...props}>Like</button>
}
Puis utilisez-le partout :
function Header() {
  return (
    <div>
      <h1>Bienvenue</h1>
      <LikeButton />
    </div>
  )
}
À première vue, vous avez juste ajouté une indirection. En réalité vous avez créé un seul point de changement. Le jour où l'implémentation évolue, un seul fichier bouge :
function LikeButton(props) {
  return (
    <Button variant="ghost" size="sm" {...props}>
      Like
    </Button>
  )
}
Zéro modification ailleurs. C'est tout l'intérêt du pattern.

Le point clé : le spread des props

Le {...props} n'est pas un détail cosmétique, c'est ce qui rend le composant réellement réutilisable. Sans lui, votre proxy devient un mur : impossible de passer un onClick, un disabled ou un aria-label sans retoucher le composant à chaque fois.
function LikeButton(props) {
  return <button {...props}>Like</button>
}

// tout fonctionne, sans rien changer au proxy
<LikeButton onClick={handleLike} disabled={isPending} aria-label="Aimer" />
function LikeButton({onClick}) {
  return <button onClick={onClick}>Like</button



Un proxy qui ne transmet pas ses props est pire que pas de proxy du tout : les attributs passent à la trappe sans erreur. Vous cherchez le bug dans le parent alors qu'il est dans le wrapper.

En TypeScript

Typez les props avec celles de l'élément que vous enveloppez, et vous héritez automatiquement de tout ce que l'élément accepte :
import type {ComponentProps} from 'react'

type LikeButtonProps = ComponentProps<'button'>

export function LikeButton(props: LikeButtonProps) {
  return <button {...props}>Like</button>
}
Même chose pour envelopper un composant existant plutôt qu'un élément HTML :
import type {ComponentProps} from 'react'

import {Button} from '@/components/ui/button'

type LikeButtonProps = ComponentProps<typeof Button>

export function LikeButton(props: LikeButtonProps) {
  return (
    <Button variant="ghost" size="sm" {...props}>
      Like
    </Button>
  )
}
Avec React 19, la ref est une prop comme les autres : elle est incluse dans ComponentProps et transmise par le spread. Plus besoin de forwardRef pour écrire un proxy transparent.

Ordre des props : qui gagne ?

Détail qui compte : la position du spread décide qui a le dernier mot.
// valeurs par défaut — l'appelant peut les remplacer
<Button variant="ghost" {...props} />

// valeurs imposées — l'appelant ne peut plus les changer
<Button {...props} variant="ghost" />
La première forme est presque toujours la bonne : elle donne des défauts sans enfermer. Gardez la seconde pour ce qui ne doit jamais varier, comme un type="button" qui éviterait une soumission de formulaire accidentelle.

Les vrais cas d'usage

1

Envelopper une librairie tierce

Tous vos boutons passent par votre composant maison plutôt que directement par celui de la librairie. Le jour où vous changez de librairie UI, vous réécrivez une poignée de fichiers, pas votre application.
2

Fixer une convention produit

Vos liens externes doivent toujours porter target="_blank" et rel="noopener noreferrer" ? Un proxy le garantit une fois pour toutes, au lieu de compter sur la vigilance de chacun en revue de code.
3

Brancher un comportement transverse

Analytics, log, état de chargement : le proxy est l'endroit naturel pour ajouter un comportement à tous les usages d'un composant d'un coup.
4

Absorber une migration

Pendant un changement d'API, le proxy traduit l'ancienne interface vers la nouvelle. Le reste du code continue de tourner pendant que vous migrez.

Un exemple concret : le lien externe

import type {ComponentProps} from 'react'

type ExternalLinkProps = ComponentProps<'a'>

export function ExternalLink(props: ExternalLinkProps) {
  return <a target="_blank" rel="noopener noreferrer" {...props} />
}
Six lignes, et une faille de sécurité (rel oublié sur un target="_blank") devient structurellement impossible dans votre application.

Quand ne PAS en faire

Le pattern est simple, donc tentant. Deux garde-fous :
SituationVerdict
Un composant utilisé à trois endroits ou plusBon candidat
Une convention à garantir (sécurité, a11y)Bon candidat, même pour deux usages
Un usage unique, sans perspective de réemploiInutile — vous ajoutez une indirection pour rien
Un proxy qui enveloppe un proxy qui enveloppe…Signal d'alarme : aplatissez
La bonne question n'est pas « est-ce que ça se répète ? » mais « qu'est-ce qui va changer ? ». On isole ce qui bouge, pas ce qui se ressemble.

À retenir

Un Proxy Component, c'est trois lignes de code pour transformer un changement global en changement local. Le pattern ne demande aucune librairie, aucune abstraction sophistiquée : juste la discipline de ne pas appeler directement une implémentation depuis quarante endroits. C'est exactement l'esprit du principe DRY — non pas « ne jamais écrire deux fois la même chose », mais « n'avoir qu'un seul endroit à modifier quand une décision change ».
>
}
// ignoré en silence : le proxy ne les transmet pas
<LikeButton disabled={isPending} aria-label="Aimer" />