Auf Ereignisse reagieren
React ermöglicht es Ihnen,Ereignis-Handlerzu Ihrem JSX hinzuzufügen. Ereignis-Handler sind Ihre eigenen Funktionen, die als Reaktion auf Interaktionen wie Klicken, Überfahren, Fokussieren von Formulareingaben usw. ausgelöst werden.
Sie werden lernen
- Verschiedene Möglichkeiten, einen Ereignis-Handler zu schreiben
- Wie Sie Ereignisbehandlungslogik von einer übergeordneten Komponente übergeben
- Wie Ereignisse sich ausbreiten und wie Sie sie stoppen können
Ereignis-Handler hinzufügen
Um einen Ereignis-Handler hinzuzufügen, definieren Sie zuerst eine Funktion undübergeben sie dann als Propan das entsprechende JSX-Tag. Hier ist beispielsweise ein Button, der noch nichts tut:
Sie können ihn dazu bringen, eine Nachricht anzuzeigen, wenn ein Benutzer klickt, indem Sie diese drei Schritte befolgen:
- Deklarieren Sie eine Funktion namens
handleClickinnerhalbIhrerButton-Komponente. - Implementieren Sie die Logik innerhalb dieser Funktion (verwenden Sie
alert, um die Nachricht anzuzeigen). - Fügen Sie
onClick={handleClick}zum<button>JSX hinzu.
Sie haben diehandleClick-Funktion definiert und sie dannals Prop übergebenan<button>.handleClickist einEreignis-Handler.Ereignis-Handler-Funktionen:
- Werden normalerweiseinnerhalbIhrer Komponenten definiert.
- Haben Namen, die mit
handlebeginnen, gefolgt vom Namen des Ereignisses.
Konventionsgemäß ist es üblich, Ereignis-Handler alshandlegefolgt vom Ereignisnamen zu benennen. Sie werden oftonClick={handleClick},onMouseEnter={handleMouseEnter}usw. sehen.
Alternativ können Sie einen Ereignis-Handler inline im JSX definieren:
Oder, prägnanter, mit einer Pfeilfunktion:
Alle diese Stile sind gleichwertig. Inline-Ereignis-Handler sind praktisch für kurze Funktionen.
Fallstrick
Funktionen, die an Ereignis-Handler übergeben werden, müssen übergeben, nicht aufgerufen werden. Zum Beispiel:
| Funktion übergeben (korrekt) | Funktion aufrufen (falsch) |
|---|---|
<button onClick={handleClick}> | <button onClick={handleClick()}> |
Der Unterschied ist subtil. Im ersten Beispiel wird diehandleClick-Funktion alsonClick-Ereignis-Handler übergeben. Dies weist React an, sie sich zu merken und Ihre Funktion nur dann aufzurufen, wenn der Benutzer auf den Button klickt.
Im zweiten Beispiel feuert das()am Ende vonhandleClick()die Funktionsofortwährend desRenderings, ohne jegliche Klicks. Das liegt daran, dass JavaScript innerhalb derJSX { und }sofort ausgeführt wird.
Wenn Sie Code inline schreiben, zeigt sich derselbe Fallstrick auf eine andere Weise:
| Funktion übergeben (korrekt) | Funktion aufrufen (falsch) |
|---|---|
<button onClick={() => alert('...')}> | <button onClick={alert('...')}> |
Das Übergeben von Inline-Code wie diesem wird nicht beim Klicken ausgelöst – es wird jedes Mal ausgelöst, wenn die Komponente gerendert wird:
Wenn Sie Ihren Ereignis-Handler inline definieren möchten, wickeln Sie ihn in eine anonyme Funktion wie folgt ein:
Anstatt den Code bei jedem Rendering auszuführen, erstellt dies eine Funktion, die später aufgerufen werden soll.
In beiden Fällen ist das, was Sie übergeben möchten, eine Funktion:
<button onClick={handleClick}>übergibt diehandleClick-Funktion.<button onClick={() => alert('...')}>übergibt die() => alert('...')-Funktion.
Props in Ereignis-Handlern lesen
Da Ereignis-Handler innerhalb einer Komponente deklariert werden, haben sie Zugriff auf die Props der Komponente. Hier ist ein Button, der bei einem Klick eine Warnung mit seinermessage-Prop anzeigt:
Dadurch können diese beiden Schaltflächen unterschiedliche Meldungen anzeigen. Versuche, die an sie übergebenen Meldungen zu ändern.
Event-Handler als Props übergeben
Oft möchtest du, dass die übergeordnete Komponente den Event-Handler einer untergeordneten Komponente festlegt. Betrachte Schaltflächen: Je nachdem, wo du eineButton-Komponente verwendest, möchtest du möglicherweise eine andere Funktion ausführen – vielleicht eine, die einen Film abspielt, und eine andere, die ein Bild hochlädt.
Um dies zu erreichen, übergibst du einen Prop, den die Komponente von ihrer übergeordneten Komponente erhält, als Event-Handler, wie folgt:
Hier rendert dieToolbar-Komponente einenPlayButtonund einenUploadButton:
PlayButtonübergibthandlePlayClickalsonClick-Prop an den darin enthaltenenButton.UploadButtonübergibt() => alert('Uploading!')alsonClick-Prop an den darin enthaltenenButton.
Schließlich akzeptiert deineButton-Komponente einen Prop namensonClick. Sie übergibt diesen Prop direkt an den eingebauten Browser-<button>mitonClick={onClick}. Dies teilt React mit, die übergebene Funktion beim Klick aufzurufen.
Wenn du einDesignsystemverwendest, ist es üblich, dass Komponenten wie Schaltflächen Stile enthalten, aber kein Verhalten festlegen. Stattdessen geben Komponenten wiePlayButtonundUploadButtonEvent-Handler weiter.
Benennung von Event-Handler-Props
Eingebaute Komponenten wie<button>und<div>unterstützen nurBrowser-EreignisnamenwieonClick. Wenn du jedoch deine eigenen Komponenten erstellst, kannst du ihre Event-Handler-Props beliebig benennen.
Gemäß Konvention sollten Event-Handler-Props mitonbeginnen, gefolgt von einem Großbuchstaben.
Zum Beispiel hätte derButton-Komponente ihronClick-Prop onSmashgenannt werden können:
In diesem Beispiel zeigt<button onClick={onSmash}>, dass der Browser-<button>(Kleinbuchstaben) immer noch einen Prop namensonClickbenötigt, aber der Prop-Name, den deine benutzerdefinierteButton-Komponente erhält, liegt bei dir!
Wenn deine Komponente mehrere Interaktionen unterstützt, könntest du Event-Handler-Props nach anwendungsspezifischen Konzepten benennen. Zum Beispiel erhält dieseToolbar-Komponente die Event-HandleronPlayMovieundonUploadImage:
Beachten Sie, dass dieApp-Komponente nicht wissen muss,wasToolbar mit onPlayMovieoderonUploadImagemacht. Das ist ein Implementierungsdetail derToolbar. Hier übergibtToolbarsie alsonClick-Handler an ihreButtons, aber sie könnte sie später auch über eine Tastenkombination auslösen. Das Benennen von Props nach anwendungsspezifischen Interaktionen wieonPlayMoviegibt Ihnen die Flexibilität, später zu ändern, wie sie verwendet werden.
Hinweis
Verwenden Sie für Ihre Event-Handler die passenden HTML-Tags. Um beispielsweise Klicks zu behandeln, verwenden Sie<button onClick={handleClick}>anstelle von<div onClick={handleClick}>. Die Verwendung eines echten Browser-<button>ermöglicht integrierte Browser-Verhaltensweisen wie Tastaturnavigation. Wenn Ihnen das Standard-Styling eines Buttons im Browser nicht gefällt und Sie ihn wie einen Link oder ein anderes UI-Element aussehen lassen möchten, können Sie dies mit CSS erreichen.Erfahren Sie mehr über das Schreiben von barrierefreiem Markup.
Event-Propagation
Event-Handler fangen auch Events von allen Kindern Ihrer Komponente ab. Man sagt, dass ein Event im Baum „aufsteigt“ oder „propagiert“: Es beginnt dort, wo das Event stattgefunden hat, und steigt dann im Baum nach oben.
Diese<div>enthält zwei Buttons. Sowohl die<div>als auchjeder Button haben ihre eigenenonClick-Handler. Welche Handler werden Ihrer Meinung nach ausgelöst, wenn Sie auf einen Button klicken?
Wenn Sie auf einen der Buttons klicken, wird zuerst dessenonClickausgeführt, gefolgt vom<div>-ElternteilonClick. Es erscheinen also zwei Meldungen. Wenn Sie auf die Toolbar selbst klicken, wird nur der<div>-ElternteilonClickausgeführt.
Fallstrick
Alle Events propagieren in React, außeronScroll, das nur auf dem JSX-Tag funktioniert, an dem Sie es anhängen.
Propagation stoppen
Event-Handler erhalten einEvent-Objektals ihr einziges Argument. Üblicherweise wird esegenannt, was für „Event“ steht. Sie können dieses Objekt verwenden, um Informationen über das Event zu lesen.
Dieses Event-Objekt ermöglicht es Ihnen auch, die Propagation zu stoppen. Wenn Sie verhindern möchten, dass ein Event übergeordnete Komponenten erreicht, müssen Siee.stopPropagation()aufrufen, wie es dieseButton-Komponente tut:
Wenn Sie auf einen Button klicken:
- React ruft den an
onClickübergebenen Event-Handler von<button>auf. - Dieser Handler, definiert in
Button, führt folgende Schritte aus:- Ruft
e.stopPropagation()auf, um die weitere Ausbreitung des Events zu verhindern. - Ruft die
onClick-Funktion auf, die als Prop von derToolbar-Komponente übergeben wurde.
- Ruft
- Diese Funktion, definiert in der
Toolbar-Komponente, zeigt die eigene Alert-Meldung der Schaltfläche an. - Da die Ausbreitung gestoppt wurde, wird der
<div>-Eltern-onClick-Handlernichtausgeführt.
Aufgrund vone.stopPropagation()zeigt ein Klick auf die Schaltflächen jetzt nur noch eine einzelne Alert-Meldung (vom<button>) anstatt zwei (vom<button>und dem übergeordneten Toolbar-<div>). Das Klicken einer Schaltfläche ist nicht dasselbe wie das Klicken auf die umgebende Toolbar, daher ist das Stoppen der Ausbreitung für diese Benutzeroberfläche sinnvoll.
Handler übergeben als Alternative zur Ausbreitung
Beachten Sie, wie dieser Klick-Handler eine Codezeile ausführtund danndie von der Elternkomponente übergebeneonClick-Prop aufruft:
Sie könnten diesem Handler auch weiteren Code hinzufügen, bevor Sie den Eltern-onClick-Event-Handler aufrufen. Dieses Muster bietet eineAlternativezur Ausbreitung. Es ermöglicht der untergeordneten Komponente, das Ereignis zu behandeln, während die Elternkomponente zusätzliches Verhalten festlegen kann. Im Gegensatz zur Ausbreitung ist es nicht automatisch. Der Vorteil dieses Musters ist jedoch, dass Sie die gesamte Kette des Codes, der als Ergebnis eines Ereignisses ausgeführt wird, klar nachvollziehen können.
Wenn Sie sich auf die Ausbreitung verlassen und es schwierig ist, nachzuvollziehen, welche Handler ausgeführt werden und warum, versuchen Sie stattdessen diesen Ansatz.
Standardverhalten verhindern
Einige Browser-Ereignisse haben ein damit verbundenes Standardverhalten. Zum Beispiel lädt ein<form>-Submit-Ereignis, das auftritt, wenn eine darin enthaltene Schaltfläche geklickt wird, standardmäßig die gesamte Seite neu:
Sie könnene.preventDefault()auf dem Ereignisobjekt aufrufen, um dies zu verhindern:
Verwechseln Sie nichte.stopPropagation()unde.preventDefault(). Beide sind nützlich, aber nicht miteinander verwandt:
- e.stopPropagation()verhindert, dass die Event-Handler der darüberliegenden Tags ausgelöst werden.
- e.preventDefault()verhindert das Standard-Browserverhalten für die wenigen Events, die eines haben.
Können Event-Handler Nebeneffekte haben?
Absolut! Event-Handler sind der beste Ort für Nebeneffekte.
Im Gegensatz zu Rendering-Funktionen müssen Event-Handler nichtreinsein, daher sind sie ein idealer Ort, um etwas zuändern– zum Beispiel den Wert einer Eingabe als Reaktion auf Tippen zu ändern oder eine Liste als Reaktion auf einen Knopfdruck. Um jedoch Informationen zu ändern, benötigt man zunächst eine Möglichkeit, sie zu speichern. In React geschieht dies durch die Verwendung vonState, dem Speicher einer Komponente.Auf der nächsten Seite erfährst du alles darüber.
Zusammenfassung
- Du kannst Events behandeln, indem du eine Funktion als Prop an ein Element wie
<button>übergibst. - Event-Handler müssen übergeben werden,nicht aufgerufen!
onClick={handleClick}, nichtonClick={handleClick()}. - Du kannst eine Event-Handler-Funktion separat oder inline definieren.
- Event-Handler werden innerhalb einer Komponente definiert, sodass sie auf Props zugreifen können.
- Du kannst einen Event-Handler in einem Elternteil deklarieren und ihn als Prop an ein Kind weitergeben.
- Du kannst eigene Event-Handler-Props mit anwendungsspezifischen Namen definieren.
- Events breiten sich nach oben aus. Rufe
e.stopPropagation()mit dem ersten Argument auf, um dies zu verhindern. - Events können unerwünschtes Standard-Browserverhalten haben. Rufe
e.preventDefault()auf, um dies zu verhindern. - Das explizite Aufrufen einer Event-Handler-Prop von einem Kind-Handler ist eine gute Alternative zur Propagation.
Probieren Sie einige Herausforderungen aus
Challenge 1 of 2:Reparieren Sie einen Event-Handler #
Ein Klick auf diese Schaltfläche soll den Seitenhintergrund zwischen Weiß und Schwarz umschalten. Allerdings passiert nichts, wenn Sie darauf klicken. Beheben Sie das Problem. (Machen Sie sich keine Sorgen über die Logik innerhalb von handleClick – dieser Teil ist in Ordnung.)
