Gestion des événements React

La gestion des événements des éléments React est similaire à celle des éléments DOM. Cependant, il existe quelques différences syntaxiques :

  • Les noms d'attributs de liaison d'événements React utilisent le camelCase, et non les minuscules.
  • Avec la syntaxe JSX, vous devez passer une fonction comme gestionnaire d'événement, plutôt qu'une chaîne (l'approche de l'élément DOM).

L'approche HTML habituelle est :

<button onclick="activateLasers()">
  激活按钮
</button>

Dans React, l'approche est :

<button onClick={activateLasers}>
  激活按钮
</button>

Une autre différence dans React est que vous ne pouvez pas utiliser returnfalsepour empêcher le comportement par défaut ; vous devez explicitement utiliserpreventDefault。

Par exemple, en HTML, nous empêchons généralement un lien d'ouvrir une nouvelle page par défaut comme ceci :
<a href="../index.html" onclick="console.log('点击链接'); return false">
  点我
</a>

Dans React, l'approche est :

function ActionLink() { function handleClick(e) { e.preventDefault(); console.log('Lien cliqué'); } return ( <a href="#" onClick={handleClick}> Cliquez-moi </a> ); }

Dans l'exemple, e est un événement synthétique.

Lorsque vous utilisez React, vous n'avez généralement pas besoin d'utiliser addEventListener pour ajouter un écouteur à un élément DOM après sa création. Vous devez seulement fournir un écouteur lorsque l'élément est initialement rendu.

Lorsque vous définissez un composant à l'aide de la syntaxe de classe ES6, le gestionnaire d'événements devient une méthode de la classe. Par exemple, le composant Toggle ci-dessous affiche un bouton qui permet aux utilisateurs de basculer l'état de l'interrupteur :

Exemple

class Toggle extends React.Component { constructor(props) { super(props); this.state = {isToggleOn: true}; //Cette liaison est nécessaire pour que `this` puisse être utilisé dans la fonction de rappel this.handleClick = this.handleClick.bind(this); } handleClick() { this.setState(prevState => ({ isToggleOn: !prevState.isToggleOn })); } render() { return ( <button onClick={this.handleClick}> {this.state.isToggleOn ? 'ACTIVÉ' : 'DÉSACTIVÉ'} </button> ); } } const root = ReactDOM.createRoot(document.getElementById("root")); root.render( <Toggle />, document.getElementById('exemple') );

Essayez-le »

Vous devez être prudent avec this dans les fonctions de rappel JSX. Les méthodes de classe ne sont pas liées à this par défaut. Si vous oubliez de lier this.handleClick et de le passer à onClick, la valeur de this sera undefined lorsque vous appelez la fonction.

En général, si vous n'ajoutez pas () après une méthode, par exempleonClick={this.handleClick}, vous devez lier this à cette méthode.

Si l'utilisation de bind vous dérange, il existe deux façons de résoudre ce problème. Si vous utilisez la syntaxe expérimentale des initialiseurs de propriété, vous pouvez utiliser des initialiseurs de propriété pour lier correctement les fonctions de rappel :

class LoggingButton extends React.Component { //Cette syntaxe garantit que `this` est lié dans handleClick //Ceci est juste un test handleClick = () => { console.log('ceci est :', this); } render() { return ( <button onClick={this.handleClick}> Cliquez moi </button> ); } }

Si vous n'utilisez pas la syntaxe d'initialisation de propriété, vous pouvez utiliser des fonctions fléchées dans la fonction de rappel :

class LoggingButton extends React.Component { handleClick() { console.log('ceci est :', this); } render() { //Cette syntaxe garantit que `this` est lié à l'intérieur de handleClick return ( <button onClick={(e) => this.handleClick(e)}> Cliquez- moi </button> ); } }

Un problème avec cette syntaxe est qu'une fonction de rappel différente est créée chaque fois que LoggingButton effectue un rendu. Dans la plupart des cas, cela ne pose pas de problème. Toutefois, si cette fonction de rappel est passée comme prop à des composants de niveau inférieur, ces composants peuvent effectuer des re-rendus supplémentaires. Nous recommandons généralement de lier dans le constructeur ou d'utiliser la syntaxe d'initialisation de propriété pour éviter ce type de problème de performance.


Passer des arguments aux gestionnaires d'événements

Habituellement, nous passons des arguments supplémentaires aux gestionnaires d'événements. Par exemple, si id est l'id de la ligne que vous voulez supprimer, chacune des deux méthodes suivantes permet de passer des arguments au gestionnaire d'événements :

<button onClick={(e) => this.deleteRow(id, e)}>Delete Row</button>
<button onClick={this.deleteRow.bind(this, id)}>Delete Row</button>
Les deux approches ci-dessus sont équivalentes.

Dans les deux exemples ci-dessus, le paramètre e, en tant qu'objet d'événement React, sera passé comme deuxième argument. Avec l'approche par fonction fléchée, l'objet d'événement doit être passé explicitement, mais avec l'approche bind, l'objet d'événement et les arguments supplémentaires seront passés implicitement.

Il convient de noter que lors du passage d'arguments à une fonction d'écoute via bind, pour une fonction d'écoute définie dans un composant de classe, l'objet d'événement e doit venir après les arguments passés, par exemple :

class Popper extends React.Component{ constructor(){ super(); this.state = {name:'Hello world!'}; } preventPop(name, e){ //L'objet d'événement e doit être placé en dernier e.preventDefault(); alert(name); } render(){ return ( <div> <p>hello</p> {/*Passer des arguments via la méthode bind().*/} <a href="https://reactjs.org" onClick={this.preventPop.bind(this,this.state.name)}>Cliquez</a> </div> ); } }
Autres extensions