
Comprendre et utiliser les PropTypes dans React
Publié le le
Combien de fois avez-vous passé des heures à déboguer un composant React, pour finalement découvrir qu'une prop était mal typée ou manquante ? Ce genre de bug silencieux peut vite transformer une journée productive en cauchemar de débogage.
C'est exactement là que les PropTypes entrent en jeu. Cet outil de validation vous permet de définir un "contrat" clair pour vos composants : quelles props ils acceptent, de quel type, lesquelles sont obligatoires. Résultat ? Les erreurs remontent en surface dès le développement, avant d'atteindre vos utilisateurs.
Dans cet article, nous verrons comment maîtriser les PropTypes pour écrire du code React plus robuste, pourquoi ils gardent toute leur utilité même à l'ère de TypeScript, et quelles pratiques adopter pour en tirer le maximum.
Pourquoi adopter les PropTypes ?
Imaginez pouvoir attraper vos erreurs avant même qu'elles n'atteignent le navigateur. C'est exactement ce que vous offrent les PropTypes, et bien plus encore :
Fini les bugs silencieux. Plus besoin de chercher pendant des heures pourquoi votre composant ne s'affiche pas correctement. Les PropTypes vous alertent instantanément si vous passez un string là où un nombre est attendu, ou si vous oubliez une prop critique.
Une documentation qui ne ment jamais. Contrairement aux commentaires qui finissent souvent obsolètes, les PropTypes reflètent toujours la réalité de votre code. Un coup d'œil aux PropTypes d'un composant et vous savez immédiatement comment l'utiliser.
Évolution sereine du code. Besoin de modifier l'API d'un composant ? Les PropTypes vous montrent instantanément tous les endroits qui nécessitent une mise à jour. Plus de refactoring à l'aveugle.
Et avec TypeScript ? Si vous utilisez déjà TypeScript, les PropTypes peuvent sembler redondants. Pourtant, ils gardent leur intérêt : TypeScript vérifie vos types à la compilation, mais les PropTypes vous protègent au runtime quand les données viennent d'une API externe ou d'un composant JavaScript non typé.
Installation et mise en place
Les PropTypes ne font plus partie de React depuis la version 15.5, ils vivent maintenant dans leur propre package. Une ligne de commande et c'est parti :
npm install prop-types
Ensuite, un simple import dans vos composants :
import PropTypes from 'prop-types';
Premier exemple concret
Prenons un composant utilisateur classique. Sans PropTypes, impossible de savoir quelles props il attend. Avec PropTypes, l'attendu devient plus clair:
import React from 'react';
import PropTypes from 'prop-types';
function UserCard({ name, age, isActive }) {
return (
<div className="user-card">
<h3>{name}</h3>
<p>Age: {age}</p>
<span className={`status ${isActive ? 'active' : 'inactive'}`}>
{isActive ? 'Online' : 'Offline'}
</span>
</div>
);
}
UserCard.propTypes = {
name: PropTypes.string.isRequired,
age: PropTypes.number,
isActive: PropTypes.bool,
};
export default UserCard;
Par où commencer avec les PropTypes
Pas la peine de tout apprendre d'un coup. Voici les PropTypes que vous utiliserez le plus souvent, avec des exemples concrets :
String, function et boolean - la base
Button.propTypes = {
children: PropTypes.string.isRequired, // Le texte du bouton
onClick: PropTypes.func.isRequired, // L'action au clic
disabled: PropTypes.bool, // État activé/désactivé
};
Ces trois types couvrent la majorité des props que vous passerez : du texte, des fonctions de callback, et des vrais/faux.
Pour valider des objets et des listes
UserProfile.propTypes = {
user: PropTypes.shape({
name: PropTypes.string.isRequired,
email: PropTypes.string.isRequired,
}).isRequired,
tags: PropTypes.arrayOf(PropTypes.string),
};
shape
vérifie qu'un objet a bien la structure
attendue. arrayOf
fait pareil pour les tableaux.
Pour limiter les choix possibles
Alert.propTypes = {
type: PropTypes.oneOf(['success', 'error', 'warning']),
size: PropTypes.oneOf(['small', 'medium', 'large']),
};
Avec oneOf
, impossible de passer autre chose que les
valeurs autorisées. Si quelqu'un écrit "sucess" au lieu de "success", il le saura tout
de suite.
Les règles d'or des PropTypes
Après des années de projets React, quelques patterns se dégagent pour utiliser les PropTypes efficacement :
Soyez strict sur les props critiques
Ne mettez pas isRequired
partout par reflexe, mais
soyez impitoyable sur les props sans lesquelles votre composant plante. Un bouton sans
onClick
? Required. Un avatar sans
src
? Required.
Button.propTypes = {
onClick: PropTypes.func.isRequired, // Le composant n'a pas de sens sans ça
children: PropTypes.node.isRequired, // Que ferait un bouton vide ?
variant: PropTypes.oneOf(['primary', 'secondary']), // Optionnel, on a un défaut
};
Combinez PropTypes et defaultProps intelligemment
Les defaultProps
ne sont pas juste des valeurs par
défaut, ils documentent aussi vos intentions. Ils disent "voici le comportement normal,
mais vous pouvez le personnaliser".
function NotificationCard({ type, message, autoClose, duration }) {
// Logique du composant...
}
NotificationCard.propTypes = {
type: PropTypes.oneOf(['success', 'error', 'warning', 'info']),
message: PropTypes.string.isRequired,
autoClose: PropTypes.bool,
duration: PropTypes.number, // en millisecondes
};
NotificationCard.defaultProps = {
type: 'info',
autoClose: true,
duration: 5000,
};
Ici, impossible de se tromper : le message est obligatoire, tout le reste a des valeurs sensées par défaut. Un développeur qui découvre ce composant sait immédiatement comment l'utiliser.
Testez vos PropTypes en conditions réelles
Les PropTypes ne servent à rien s'ils ne catchent pas les vrais problèmes. Testez avec des données foireuses : objets null, arrays vides, strings au lieu de numbers. C'est là que vous verrez si vos validations tiennent la route.
PropTypes vs TypeScript
La question revient systématiquement : faut-il migrer vers TypeScript ou rester sur PropTypes ? La réponse dépend surtout de votre contexte, pas de dogmes techniques.
Quand PropTypes gardent l'avantage
Sur du legacy JavaScript. Vous avez une codebase JS existante de 50k lignes ? Les PropTypes s'ajoutent sans friction, composant par composant. TypeScript demanderait une migration massive avec risque de tout casser.
Pour des prototypes rapides. Vous testez une idée, vous itérez vite ? PropTypes donnent une validation basique sans la lourdeur de setup TypeScript. Parfait pour du jetable ou des POCs.
Validation runtime indispensable. Vos données viennent d'APIs externes non fiables ? PropTypes valident en production là où TypeScript se contente de la compilation.
Où TypeScript écrase la concurrence
Sur de gros projets. Plus de 20 développeurs, des milliers de composants ? L'autocomplétion, les refactorings automatiques et la détection d'erreurs de TypeScript deviennent indispensables.
Pour l'écosystème. Libs tierces typées, meilleure intégration IDE, outillage plus riche. Une fois qu'on y goûte, difficile de revenir en arrière.
Le compromis réaliste
Dans un projet TypeScript, gardez PropTypes sur les composants qui reçoivent des données externes (APIs, props depuis du JS legacy). Le double filet de sécurité compile-time + runtime n'est pas du luxe quand les enjeux sont importants.
interface UserCardProps {
user: {
id: string;
name: string;
email: string;
};
onEdit: (id: string) => void;
}
function UserCard({ user, onEdit }: UserCardProps) {
// Composant...
}
// Double validation pour les données d'API
UserCard.propTypes = {
user: PropTypes.shape({
id: PropTypes.string.isRequired,
name: PropTypes.string.isRequired,
email: PropTypes.string.isRequired,
}).isRequired,
onEdit: PropTypes.func.isRequired,
};
Pour résumer
Les PropTypes ne révolutionneront pas votre façon de coder, mais ils évitent les bugs bêtes qui plombent une journée de dev. Quelques lignes de validation en plus, et vous dormez mieux la nuit en sachant que vos composants ne planteront pas à cause d'une prop foireuse.
Si vous êtes sur du JavaScript pur, adoptez-les sans hésiter. Sur TypeScript, gardez-les pour les composants exposés aux données externes. Et si vous débutez un gros projet en 2025, partez directement sur TypeScript - mais n'oubliez pas que PropTypes ont encore leur place dans l'écosystème.
L'essentiel ? Choisissez l'outil qui correspond à votre contexte, pas à la mode du moment.
Les questions qu'on se pose vraiment
J'ai déjà TypeScript, pourquoi m'embêter avec PropTypes ?
Bonne question ! TypeScript vous protège pendant que vous codez, mais PropTypes vous
rattrapent quand les choses déconnent en production. Genre quand votre API renvoie
null
au lieu d'un objet, ou qu'un vieux composant JS passe n'importe
quoi. C'est votre filet de sécurité runtime.
Comment je valide une liste d'utilisateurs avec leurs détails ?
C'est là que arrayOf
et
shape
deviennent vos meilleurs amis :
users: PropTypes.arrayOf(
PropTypes.shape({
id: PropTypes.string.isRequired,
name: PropTypes.string.isRequired,
email: PropTypes.string,
})
).isRequired
Ça valide que vous avez bien un tableau, avec des objets qui ont la bonne structure.
Ça va pas ralentir mon app ?
Pas du tout ! Les PropTypes ne tournent qu'en développement. Dès que vous buildez pour la production, ils disparaissent complètement. Zéro impact sur vos utilisateurs finaux.
Ça marche avec les hooks et les composants fonctionnels ?
Bien sûr ! Que votre composant soit une class, une fonction, qu'il utilise des hooks ou pas, les PropTypes s'en fichent. Ils regardent juste ce qui rentre dans votre composant, pas comment il fonctionne à l'intérieur.
C'est pas un truc du passé maintenant ?
Pas vraiment. Oui, TypeScript a le vent en poupe, mais PropTypes ont encore du sens sur plein de projets : du JavaScript legacy, des prototypes rapides, ou quand vous voulez une validation runtime en plus de TypeScript. Choisissez selon votre contexte, pas selon les tendances.