Verwalten von Benutzerereignissen in React mit TypeScript
Dieses Tutorial zeigt, wie Sie Benutzerereignisse in React mit TypeScript verwalten, indem Sie bei den Aktionen eines Benutzers eine onClick
-Funktion von Komponente zu Komponente übergeben.
Verwalten von Benutzerereignissen in React mit TypeScript
Wir werden create-react-app
verwenden, um schnell ein neues React-Projekt zu starten und auszuführen.
npx create-react-app my-app --template typescript
cd my-app
npm run start
Nachdem wir die erforderlichen Pakete installiert und den Entwicklungsserver gestartet haben, gehen wir zu src/App.tsx
, löschen den gesamten Boilerplate-Code und lassen eine leere Komponente.
import React from "react";
function Message() {
return <div></div>;
}
export default Message;
Jetzt fügen wir dem div
eine Schaltfläche hinzu, auf die der Benutzer klicken kann, und wir antworten, indem wir eine Funktion mit einer Warnung innerhalb der onClick
-Prop übergeben.
function Message() {
return (
<div>
<button
onClick={() => {
alert("I was clicked!");
}}>
Click Me!
</button>
</div>
);
}
Nichts ändert sich von Vanilla React zu TypeScript, aber die Dinge sind anders, wenn wir wollen, dass die onClick
-Funktion als Prop der Message
-Komponente übergeben wird. Um dies zu zeigen, erstellen wir eine weitere Komponente namens Game
, die Message
als Kind hat.
function Game() {
return (
<div>
<Message></Message>
</div>
);
}
export default Game;
Und wir werden Message
dazu bringen, seine onClick
-Funktion und text
als Requisiten von Game
zu erhalten.
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>
);
}
Wir erhalten jedoch die folgenden Kompilierungsfehler, wenn wir diesen Code ausführen.
Binding element 'onClick' implicitly has an 'any' type.
Binding element 'text' implicitly has an 'any' type.
In Vanilla JavaScript verursacht dies keinen Fehler, aber TypeScript wirft einen, da die Props onClick
und text
von Message
implizit einen any
-Typ haben, d. h. wir haben nicht deklariert, welchen Typ diese Props haben sollten Laden. Wir müssen eine Schnittstelle erstellen, die angibt, welchen Typ die Requisiten der Nachricht
haben sollen, um dies zu lösen.
interface MessageProps {
text: string;
onClick: {};
}
Der Wert, den das Prop text
haben soll, ist einfach zu deklarieren, da es nur ein String ist. Schwieriger ist aber der Wert für onClick
.
onClick
ist mehr als eine normale Funktion, da es eine event
-Eigenschaft hat und eine vorgegebene Eigenschaft des button
-Elements ist. Um also onClick
zu definieren, benötigen wir eine vordefinierte Schnittstelle, die mit React geliefert wird, die in diesem Fall ButtonHTMLAttributes
heißt und alle Eigenschaftstypen des button
-Elements enthält.
Um es zu verwenden, müssen wir die Schnittstelle MessageProps
erweitern, um die Typen ButtonHTMLAttributes
zu speichern.
interface MessageProps extends ButtonHTMLAttributes {
text: string;
}
Dies ist jedoch nicht genug, und das Ausführen des Codes wie diesem wird einen Fehler auslösen, da die Schnittstelle ButtonHTMLAttributes
ein generischer Typ ist. Sie können sich generische Typen als Schnittstellen mit Variablen vorstellen, und um sie zu verwenden, wickeln wir sie um <>
, nachdem wir die Schnittstelle deklariert haben.
In diesem Fall benötigt die Schnittstelle ButtonHTMLAttributes
eine Variable, um zu wissen, welches HTML-Element wir verwenden, und es wird das globale HTMLButtonElement sein.
interface MessageProps extends ButtonHTMLAttributes<HTMLButtonElement> {
text: string;
}
MessageProps
enthält nicht nur die Typen für die Props text
und onClick
, sondern die Typen für alle Props eines button
-Elements. Sie können jede Requisite von einem button
zu Message
hinzufügen.
Falls Sie nur das Prop onClick
erweitern möchten, erweitern Sie die Schnittstelle nicht, erstellen einen neuen onClick
-Typ und weisen die onClick
-Eigenschaft der ButtonHTMLAttributes
mit Indexed Access Types zu.
interface MessageProps {
text: string;
onClick: ButtonHTMLAttributes<HTMLButtonElement>["onClick"];
}
Abschließend müssen wir erklären, dass die Message
-Komponente MessageProps
für ihre Requisiten auf folgende Weise verwendet.
function Message({onClick, text}: MessageProps) {
return (
<div>
<button onClick={onClick}>{text}</button>
</div>
);
}
Und wenn wir wollen, können wir den Rückgabetyp als JSX.Element
annotieren, sodass TypeScript einen Fehler auslöst, wenn wir versehentlich einen anderen Typ zurückgeben.
function Message({onClick, text}: MessageProps): JSX.Element {
return (
<div>
<button onClick={onClick}>{text}</button>
</div>
);
}
Und das wäre das Endergebnis.
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