
Typer les événements
Apprenez à typer correctement les gestionnaires d'événements (onClick, onChange, onSubmit...) en React avec TypeScript pour accéder aux propriétés de l'événement en toute sécurité.
Le défi : Accéder aux propriétés de l'événement en sécurité
La gestion des événements est au coeur de l'interactivité dans React. Que ce soit pour répondre à un clic de bouton (`onClick`), à une modification de champ de saisie (`onChange`), ou à la soumission d'un formulaire (`onSubmit`), nous écrivons des fonctions gestionnaires (event handlers) qui reçoivent un objet événement en argument.
En JavaScript simple, nous accédons aux propriétés de cet objet événement (comme `event.target.value` pour un champ de saisie) sans garantie de type. Si nous faisons une faute de frappe ou si nous essayons d'accéder à une propriété qui n'existe pas sur ce type d'événement particulier, l'erreur ne sera détectée qu'à l'exécution.
TypeScript nous permet de typer explicitement le paramètre `event` de nos gestionnaires, nous donnant ainsi accès à l'autocomplétion pour les propriétés de l'événement et garantissant que nous n'essayons pas d'accéder à des propriétés inexistantes ou de manière incorrecte. Cela rend la gestion des événements plus sûre et moins sujette aux erreurs.
Les événements synthétiques de React et leurs types
Il est important de se rappeler que React n'utilise pas directement les événements natifs du navigateur. Il enveloppe ces événements dans un système d'événements synthétiques (`SyntheticEvent`). Cet enveloppeur normalise le comportement des événements entre les différents navigateurs.
Lorsque vous utilisez TypeScript, vous ne typez pas directement avec les types d'événements natifs du DOM (comme `MouseEvent` ou `KeyboardEvent`), mais plutôt avec les types d'événements synthétiques spécifiques fournis par React. Ces types sont généralement importés depuis la bibliothèque `react`.
Le type de base est `React.SyntheticEvent`, mais il est souvent trop générique. Il est préférable d'utiliser des types plus spécifiques qui correspondent à l'événement que vous gérez et à l'élément sur lequel il se produit.
Types d'événements courants et comment les utiliser
- Evénements de souris (`onClick`, `onMouseEnter`, etc.) :
- Type : `React.MouseEvent
` - `ElementType` est le type de l'élément HTML sur lequel l'événement se produit (ex: `HTMLButtonElement`, `HTMLDivElement`).
import React from 'react'; const MyButton = () => { // Type explicite pour l'événement de clic sur un bouton const handleClick = (event: React.MouseEvent) => { console.log('Bouton cliqué!', event.currentTarget); // event.target peut nécessiter une vérification de type plus fine }; return ; }; - Type : `React.MouseEvent
- Evénements de changement (`onChange`) sur les inputs, textareas, selects :
- Type : `React.ChangeEvent
` - `ElementType` est `HTMLInputElement`, `HTMLTextAreaElement`, ou `HTMLSelectElement`.
- Permet d'accéder en toute sécurité à `event.target.value`.
import React, { useState } from 'react'; const MyInput = () => { const [value, setValue] = useState(''); // Type pour l'événement de changement sur un input const handleChange = (event: React.ChangeEvent) => { setValue(event.target.value); // Accès sécurisé à .value }; return ; }; - Type : `React.ChangeEvent
- Evénements de formulaire (`onSubmit`) :
- Type : `React.FormEvent
` - Attaché à la balise `
- N'oubliez pas d'appeler `event.preventDefault()` pour empêcher le rechargement de la page.
import React from 'react'; const MyForm = () => { const handleSubmit = (event: React.FormEvent) => { event.preventDefault(); // Important ! console.log('Formulaire soumis'); const formData = new FormData(event.currentTarget); // ... traiter formData }; return ( ); }; - Type : `React.FormEvent
- Evénements clavier (`onKeyDown`, `onKeyUp`, `onKeyPress`) :
- Type : `React.KeyboardEvent
` - Permet d'accéder à `event.key`, `event.code`, `event.altKey`, etc.
import React from 'react'; const KeyListener = () => { const handleKeyDown = (event: React.KeyboardEvent) => { if (event.key === 'Enter') { console.log('Entrée pressée!'); } }; return ; }; - Type : `React.KeyboardEvent
- Evénements de focus (`onFocus`, `onBlur`) :
- Type : `React.FocusEvent
`
- Type : `React.FocusEvent
Il existe de nombreux autres types d'événements synthétiques (TouchEvent, ClipboardEvent, DragEvent, etc.) disponibles dans `@types/react` pour couvrir la plupart des interactions DOM.
Gestion des types d'éléments génériques
Parfois, vous ne savez pas exactement sur quel type d'élément HTML un gestionnaire d'événement sera attaché, ou vous voulez créer un gestionnaire réutilisable. Dans ce cas, vous pouvez utiliser un type plus générique comme `HTMLElement` ou même `Element` comme paramètre de type générique, mais vous perdrez alors l'accès direct et sûr à des propriétés spécifiques (comme `.value` sur un `input`).
const handleGenericClick = (event: React.MouseEvent) => {
console.log('Clic sur un élément HTML:', event.currentTarget.tagName);
// event.currentTarget.value n'est pas accessible directement ici
// car tous les HTMLElements n'ont pas de propriété 'value'.
// Il faudrait faire une vérification de type:
if (event.currentTarget instanceof HTMLInputElement) {
console.log(event.currentTarget.value);
}
}; Il est généralement préférable d'être aussi spécifique que possible avec le type d'élément pour bénéficier pleinement de la sécurité de TypeScript.
Inférence de type pour les gestionnaires en ligne
Si vous définissez votre gestionnaire d'événement directement en ligne dans le JSX (ce qui est moins courant pour la logique complexe mais possible pour des cas simples), TypeScript peut souvent inférer le type de l'événement pour vous :
import React, { useState } from 'react';
const InlineHandler = () => {
const [text, setText] = useState('');
return (
onChange={(e) => setText(e.target.value)}
/>
);
};Cependant, pour une meilleure lisibilité et pour la logique plus complexe, il est généralement recommandé d'extraire les gestionnaires dans des fonctions séparées et de leur donner un type explicite.
Conclusion : Des interactions plus sûres
Typer correctement les gestionnaires d'événements en React avec TypeScript est une pratique essentielle pour éviter les erreurs d'exécution liées à l'accès incorrect aux propriétés de l'objet événement. En utilisant les types d'événements synthétiques spécifiques fournis par React (comme `React.MouseEvent`, `React.ChangeEvent`, `React.FormEvent`) et en spécifiant le type de l'élément cible, vous bénéficiez de la vérification statique, de l'autocomplétion et d'une plus grande confiance dans la robustesse de vos interactions utilisateur.