Gérer les événements utilisateur dans React avec TypeScript
Ce tutoriel montrera comment gérer les événements des utilisateurs dans React avec TypeScript en passant une fonction onClick
d’un composant à l’autre sur les actions d’un utilisateur.
Gérer les événements utilisateur dans React With TypeScript
Nous utiliserons create-react-app
pour démarrer et exécuter rapidement un nouveau projet React.
npx create-react-app my-app --template typescript
cd my-app
npm run start
Après avoir installé les packages nécessaires et démarré le serveur de développement, nous irons dans src/App.tsx
, supprimerons tout le code passe-partout et laisserons un composant vide.
import React from "react";
function Message() {
return <div></div>;
}
export default Message;
Nous allons maintenant ajouter un bouton à la div
sur lequel l’utilisateur peut cliquer, et nous répondrons en passant une fonction avec une alerte à l’intérieur de la prop onClick
.
function Message() {
return (
<div>
<button
onClick={() => {
alert("I was clicked!");
}}>
Click Me!
</button>
</div>
);
}
Rien ne change de Vanilla React à TypeScript, mais les choses sont différentes une fois que nous voulons que la fonction onClick
soit transmise en tant que prop du composant Message
. Pour le montrer, nous allons créer un autre composant appelé Jeu
qui aura Message
comme enfant.
function Game() {
return (
<div>
<Message></Message>
</div>
);
}
export default Game;
Et nous ferons en sorte que Message
reçoive sa fonction onClick
et son text
comme accessoires provenant de Game
.
function Message({onClick, text}) {
return (
<div>
<button onClick={onClick}>{text}</button>
</div>
);
}
function Game() {
return (
<div>
<Message
onClick={() => {
alert("I was clicked!");
}}
text="Click me!"></Message>
</div>
);
}
Cependant, nous obtiendrons les erreurs de compilation suivantes si nous exécutons ce code.
Binding element 'onClick' implicitly has an 'any' type.
Binding element 'text' implicitly has an 'any' type.
Dans JavaScript Vanilla, cela ne provoque pas d’erreur, mais TypeScript en génère une puisque les props onClick
et text
de Message
ont implicitement un type any
, c’est-à-dire que nous n’avons pas déclaré quel type ces props devraient boutique. Nous devons créer une interface spécifiant quel type les props du Message
doivent avoir pour résoudre ce problème.
interface MessageProps {
text: string;
onClick: {};
}
La valeur que le prop text
devrait avoir est facile à déclarer puisqu’il ne s’agit que d’une chaîne. Mais la valeur pour onClick
est plus difficile.
onClick
est plus qu’une fonction normale puisqu’il a une propriété event
, et c’est une propriété prédéterminée de l’élément button
. Donc, pour définir onClick
, nous avons besoin d’une interface prédéfinie fournie avec React, qui dans ce cas s’appelle ButtonHTMLAttributes
et contient tous les types de propriétés de l’élément button
.
Pour l’utiliser, nous devons étendre l’interface MessageProps
pour stocker les types ButtonHTMLAttributes
.
interface MessageProps extends ButtonHTMLAttributes {
text: string;
}
Cependant, cela ne suffit pas, et exécuter le code comme celui-ci générera une erreur puisque l’interface ButtonHTMLAttributes
est un Generic Type. Vous pouvez considérer les types génériques comme des interfaces avec des variables, et pour les utiliser, nous les enveloppons autour de <>
après avoir déclaré l’interface.
Dans ce cas, l’interface ButtonHTMLAttributes
a besoin d’une variable pour savoir quel élément HTML nous utilisons, et ce sera le HTMLButtonElement global.
interface MessageProps extends ButtonHTMLAttributes<HTMLButtonElement> {
text: string;
}
MessageProps
ne contient pas seulement les types des props text
et onClick
mais les types de toutes les props d’un élément button
. Vous pouvez ajouter n’importe quel accessoire d’un “bouton” à Message
.
Si vous souhaitez uniquement étendre la propriété onClick
, vous n’étendez pas l’interface, créez un nouveau type onClick
et affectez la propriété onClick
de ButtonHTMLAttributes
à l’aide de Types d’accès indexés.
interface MessageProps {
text: string;
onClick: ButtonHTMLAttributes<HTMLButtonElement>["onClick"];
}
Pour finir, nous devons déclarer que le composant Message
utilisera MessageProps
pour ses props de la manière suivante.
function Message({onClick, text}: MessageProps) {
return (
<div>
<button onClick={onClick}>{text}</button>
</div>
);
}
Et si nous le voulons, nous pouvons annoter le type de retour comme étant un JSX.Element
afin que TypeScript génère une erreur si nous renvoyons accidentellement un autre type.
function Message({onClick, text}: MessageProps): JSX.Element {
return (
<div>
<button onClick={onClick}>{text}</button>
</div>
);
}
Et ce serait le résultat final.
import React from "react";
import {ButtonHTMLAttributes} from "react";
interface MessageProps {
text: string;
onClick: ButtonHTMLAttributes<HTMLButtonElement>["onClick"];
}
function Message({onClick, text}: MessageProps): JSX.Element {
return (
<div>
<button onClick={onClick}>{text}</button>
</div>
);
}
function Game() {
return (
<div>
<Message
onClick={() => {
alert("I was clicked!");
}}
text="Click me!"></Message>
</div>
);
}
export default Game;
Juan Diego Rodríguez (also known as Monknow) is a front-end developer from Venezuela who loves to stay updated with the latest web development trends, making beautiful websites with modern technologies. But also enjoys old-school development and likes building layouts with vanilla HTML and CSS to relax.
LinkedIn