Menu

Événements React : onClick, onChange, onSubmit et plus

Les événements React sont des props comme onClick et onChange qui prennent une fonction, que React appelle avec un objet événement quand l'utilisateur agit. Apprenez à passer un gestionnaire au lieu de l'appeler, à passer des arguments, à lire e.target.value et e.key, à empêcher le rechargement des formulaires et à stopper la propagation.

Cette page contient des éditeurs exécutables - modifiez, exécutez et voyez la sortie instantanément.

React gère les événements avec des props portant le nom de l'événement en camelCase, comme onClick, onChange et onSubmit. Vous passez une fonction, et React l'appelle avec un objet événement quand l'utilisateur clique, tape ou envoie un formulaire.

Chaque clic exécute handleClick, qui met à jour le compteur et écrit dans la console sous l'aperçu. Essayez onDoubleClick à la place de onClick : seul un double clic compte désormais.

Passer la fonction, ne pas l'appeler

La prop prend une fonction, et React l'appelle plus tard. Une erreur très courante consiste à ajouter des parenthèses, ce qui appelle la fonction tout de suite, pendant le rendu, et donne à React sa valeur de retour à la place.

La console affiche "Hi, during render" avant que vous touchiez à quoi que ce soit : React a exécuté sayHi en faisant le rendu du premier bouton, et comme sayHi renvoie undefined, ce bouton n'a aucun gestionnaire. Cliquer sur Wrong ne fait rien. Cliquer sur Right affiche "Hi, Ada", car la fonction fléchée ne s'exécute qu'au clic.

La fonction fléchée est aussi le moyen de passer des arguments. onClick={() => removeItem(item.id)} crée une petite fonction pour chaque élément, et cette fonction appelle la vôtre avec le bon identifiant. Si un gestionnaire ne prend pas d'argument, passez-le par son nom : onClick={handleClick}.

Avec un setter d'état, l'erreur est pire : onClick={setCount(count + 1)} modifie l'état pendant le rendu, ce qui provoque un nouveau rendu, qui modifie à nouveau l'état, et React s'arrête avec "Too many re-renders".

L'objet événement

React passe à chaque gestionnaire un argument, l'objet événement. Il a les mêmes propriétés que l'événement du navigateur : e.target est l'élément sur lequel l'événement a eu lieu, e.key est la touche pressée, e.preventDefault() annule l'action par défaut du navigateur. React enveloppe l'événement natif dans ce qu'il appelle un événement synthétique, pour qu'il se comporte de la même façon dans tous les navigateurs ; l'original se trouve dans e.nativeEvent si vous en avez besoin.

Les deux que vous utiliserez le plus sont e.target.value dans onChange et e.key dans onKeyDown.

Tapez hooks et appuyez sur Entrée : le tag est ajouté et le champ se vide. La console affiche chaque touche, y compris Shift, Backspace et Enter, sous les noms de e.key. Appuyez sur Échap au milieu d'un mot pour l'abandonner.

Le onChange de React se déclenche à chaque frappe. En HTML classique, l'événement change d'un champ texte ne se déclenche que lorsqu'il perd le focus : cette différence est voulue, elle permet au champ et à l'état de rester alignés lettre par lettre. Les cases à cocher vous donnent e.target.checked au lieu de value. La page sur les formulaires couvre tous les types de champs.

Formulaires et preventDefault

Quand un formulaire est envoyé, l'action par défaut du navigateur est de le transmettre et de charger une nouvelle page. Dans une application React, vous voulez presque toujours gérer les données vous-même, donc le gestionnaire d'envoi commence par e.preventDefault().

Placez onSubmit sur le <form>, pas onClick sur le bouton : appuyer sur Entrée dans le champ envoie alors aussi le formulaire, et les vérifications propres au navigateur (ici required et type="email") s'exécutent d'abord. Supprimez la ligne e.preventDefault() et envoyez à nouveau : une vraie page partirait maintenant vers une nouvelle page et perdrait le message de remerciement. L'aperçu bloque cela et montre à la place ce que le formulaire enverrait, email= sans valeur, car setEmail('') avait déjà vidé le champ quand le formulaire a été lu.

React 19 permet aussi de passer une fonction à <form action={fn}>, qui reçoit les données du formulaire et réinitialise pour vous les champs non contrôlés. La page sur les formulaires montre les deux styles.

Propagation et stopPropagation

La plupart des événements remontent : après s'être exécutés sur l'élément cliqué, ils s'exécutent sur son parent, puis sur le parent du parent, jusqu'en haut. Les gestionnaires React suivent le même ordre. C'est pourquoi un clic sur un bouton dans une carte cliquable compte aussi comme un clic sur la carte.

Cliquez sur Bubbles up et la console affiche le bouton, puis le panneau intérieur, puis la carte extérieure. Cliquez sur Stops here et seul le bouton s'affiche : e.stopPropagation() met fin à la remontée. Cliquer sur le texte du panneau intérieur affiche le panneau et la carte.

Utilisez stopPropagation avec parcimonie. Un cas légitime courant est un bouton de suppression dans une ligne de liste cliquable, où cliquer sur supprimer ne doit pas aussi ouvrir la ligne. Si un parent a besoin de savoir si le clic vient d'un enfant, vérifiez e.target au lieu de stopper l'événement. Pour exécuter un gestionnaire à la descente, avant que les enfants voient l'événement, React propose des versions de capture comme onClickCapture.

preventDefault et stopPropagation sont des outils différents. Le premier annule ce que ferait le navigateur (suivre un lien, envoyer un formulaire, cocher une case). Le second empêche les autres gestionnaires d'être informés de l'événement. Appeler l'un ne fait pas l'autre.

Autres événements courants

Le même pattern couvre tous les événements que React gère. Quelques-uns que vous utiliserez souvent :

  • onFocus et onBlur se déclenchent quand un champ prend et perd le focus, pratique pour afficher la validation une fois que l'utilisateur quitte un champ.
  • onMouseEnter et onMouseLeave se déclenchent quand le pointeur entre sur un élément et en sort. Contrairement à la plupart des événements, ils ne remontent pas : déplacer le pointeur d'un parent vers son enfant ne redéclenche pas le onMouseEnter du parent.
  • onPointerDown, onPointerMove et onPointerUp fonctionnent aussi bien pour la souris, le tactile et le stylet, ce qui en fait le meilleur choix pour le glisser-déposer.
  • onScroll se déclenche quand un élément défile. Dans React, il ne remonte pas.

Chaque gestionnaire reçoit un objet événement avec les propriétés qui ont du sens pour lui : e.clientX pour les événements de pointeur, e.key pour les événements clavier, e.target pour tous.

Passer des gestionnaires en props

Les composants peuvent recevoir des gestionnaires de leur parent comme n'importe quelle autre prop. Nommez-les onSomething d'après ce qui s'est passé, et nommez la fonction qui le gère handleSomething. Cela reprend les événements natifs et rend évident quelles props sont des callbacks.

Stepper ne possède pas le nombre ; il signale les clics et le parent décide de ce qu'ils signifient. Modifiez handleDecrement pour s'arrêter à 1 au lieu de 0 et le stepper suit sans être modifié. Garder l'état dans le parent et passer des gestionnaires vers le bas est le pattern décrit dans faire remonter l'état.

Les props de gestionnaire personnalisées ne sont que des noms. onIncrement sur votre propre composant ne fait rien tant que le composant ne le passe pas au onClick d'un vrai élément, et vous pouvez lui donner les arguments que vous voulez, par exemple onSelect(item.id).

Questions fréquentes

Comment passer un paramètre à un gestionnaire onClick ?

Enveloppez l'appel dans une fonction fléchée : onClick={() => deleteItem(item.id)}. C'est la fonction fléchée que React appelle au clic, et elle appelle ensuite votre fonction avec l'argument.

Pourquoi mon onClick s'exécute-t-il au chargement de la page ?

Vous avez appelé la fonction au lieu de la passer. onClick={handleClick()} exécute handleClick pendant le rendu et passe sa valeur de retour. Écrivez onClick={handleClick} ou onClick={() => handleClick(id)}.

Quelle est la différence entre onChange en React et en HTML ?

En HTML, l'événement change d'un champ texte se déclenche quand le champ perd le focus. Le onChange de React se déclenche à chaque frappe, comme l'événement natif input, pour que l'état suive le texte pendant la saisie.

Comment empêcher un formulaire de recharger la page en React ?

Appelez e.preventDefault() au début du gestionnaire onSubmit. Placez le gestionnaire sur le <form>, pas sur le bouton d'envoi, pour qu'appuyer sur Entrée dans un champ envoie aussi le formulaire.

Qu'est-ce qu'un événement synthétique dans React ?

C'est l'objet événement que React passe à vos gestionnaires. Il enveloppe l'événement natif du navigateur avec les mêmes propriétés et méthodes (target, key, preventDefault(), stopPropagation()) et se comporte de la même façon dans tous les navigateurs. L'original est accessible via e.nativeEvent.

Illustration des langages de programmation de Coddy

Apprendre à coder avec Coddy

COMMENCER