OnClick reagieren - Ereignis mit Parameter übergeben

96

Ohne Parameter

function clickMe(e){
  //e is the event
}

<button onClick={this.clickMe}></button>

Mit Parameter

function clickMe(parameter){
  //how to get the "e" ?
}
<button onClick={() => this.clickMe(someparameter)}></button>

Ich möchte das bekommen event. Wie kann ich es bekommen?

IMOBAMA
quelle

Antworten:

174

Versuche dies:

<button onClick={(e) => {
     this.clickMe(e, someParameter)
}}>Click Me!</button>

Und in Ihrer Funktion:

function clickMe(event, someParameter){
     //do with event
}
Jyothi Babu Araja
quelle
2
Dies hatte mir einen Eslint-Fehler gegeben ( eslint.org/docs/rules/arrow-parens.html ). Ich habe die Funktionsparameter in Klammern gesetztonClick={(e) => { this.clickMe(e, someparameter) }}
kretzm
1
Ja @kretzm Wenn wir keine geschweiften Klammern angeben, fungiert es als Rückgabeausdruck, wenn es sich um eine einzelne Zeile handelt. Andernfalls müssen wir Klammern verwenden, um als Funktionskörper zu umbrechen.
Jyothi Babu Araja
4
Ich möchte nur hinzufügen, dass es sich um eine nicht empfohlene Syntax handelt. Aus den Reactjs-Dokumenten: Das Problem bei dieser Syntax besteht darin, dass bei jedem Rendern der Schaltfläche ein anderer Rückruf erstellt wird. In den meisten Fällen ist dies in Ordnung. Wenn dieser Rückruf jedoch als Requisite an niedrigere Komponenten übergeben wird, führen diese Komponenten möglicherweise ein zusätzliches erneutes Rendern durch. Wir empfehlen im Allgemeinen, im Konstruktor zu binden oder die Syntax der Klassenfelder zu verwenden, um diese Art von Leistungsproblemen zu vermeiden. Mehr Infos unter reactjs.org
northernwind
1
@Sieger. Ja, du hast recht. Wenn Sie jedoch den Kontext Ihres übergeordneten Elements in Ihrem Rückruf haben möchten, müssen Sie bei jedem Rendern einen anderen Rückruf haben. Eigentlich ist es ein Kompromiss, denke ich.
Jyothi Babu Araja
@JyothiBabuAraja Ich denke, die beste Lösung besteht darin, die data-*Attribute in HTML5 zu verwenden. Bitte sehen Sie meine Antwort unten für weitere Details.
Harry Chang
37

Mit dem ES6 können Sie dies auf kürzere Weise tun:

const clickMe = (parameter) => (event) => {
    // Do something
}

Und benutze es:

<button onClick={clickMe(someParameter)} />
Minh Kha
quelle
Behebt dies auch das Erstellen eines neuen Rückrufproblems? stackoverflow.com/questions/42597602/…
Otani Shuzo
1
Darüber hinaus können Sie mehrere Parameter senden. const clickMe = (Parameter1, Parameter2) => (Ereignis) => {// Etwas tun}
AhuraMazda
1
Dieser wird auch ausgelöst, wenn Ihre Komponente gemountet ist. Ihr Code sollte lauten:onClick={(e) => clickMe(someParameter)(e)}
Alexander Kim
Ähnlich wie bei clickMe können Sie das Ereignis auch zerstören, auch wenn Sie es nicht als Parameter definieren.
Minh Kha
Danke dafür. Es klappt. Aber warum gibt es const clickMe = (parameter) => (event) => {...} stattdessen const clickMe = (parameter) => {...}?
Zrna
17

Lösung 1

function clickMe(parameter, event){
}

<button onClick={(event) => {this.clickMe(someparameter, event)}></button>

Lösung 2 Die Verwendung der Bindungsfunktion wird in Lösung 1 als besser als die Pfeilfunktion angesehen. Beachten Sie, dass der Ereignisparameter der letzte Parameter in der Handlerfunktion sein sollte

function clickMe(parameter, event){
}

<button onClick={this.clickMe.bind(this, someParameter)}></button>
Bence Dergez
quelle
+1 für den Ereignisparameter ist das Letzte in Lösung 2. Ich habe ewig gebraucht, um zu erkennen, was ich falsch gemacht habe. Ich muss den Grund irgendwo in den Dokumenten übersehen haben.
Abelito
5

Um das Problem beim Erstellen eines neuen Rückrufs vollständig zu lösen, ist die Verwendung der data-*Attribute in HTML5 die beste Lösung, IMO. Selbst wenn Sie am Ende des Tages eine Unterkomponente extrahieren, um die Parameter zu übergeben, werden dennoch neue Funktionen erstellt.

Zum Beispiel,

const handleBtnClick = e => {
  const { id } = JSON.parse(e.target.dataset.onclickparam);
  // ...
};

<button onClick={handleBtnClick} data-onclickparam={JSON.stringify({ id: 0 })}>

Informationen zur Verwendung von data-*Attributen finden Sie unter https://developer.mozilla.org/en-US/docs/Learn/HTML/Howto/Use_data_attributes .

Harry Chang
quelle
Ich mag diesen Ansatz. Einfach und sauber
marknt15
5

Currying mit ES6 Beispiel:

const clickHandler = param => event => {
  console.log(param); // your parameter
  console.log(event.type); // event type, e.g.: click, etc.
};

Unser Button, der den Handler umschaltet:

<button onClick={(e) => clickHandler(1)(e)}>Click me!</button>

Wenn Sie diesen Funktionsausdruck ohne Ereignisobjekt aufrufen möchten, rufen Sie ihn folgendermaßen auf:

clickHandler(1)();

Da React synthetische Ereignisse verwendet (ein Wrapper für native Ereignisse), gibt es eine Ereignispooling-Funktion. Wenn Sie Ihr eventObjekt also asynchron verwenden möchten , müssen Sie Folgendes verwenden event.persist():

const clickHandler = param => event => {
  event.persist();
  console.log(event.target);
  setTimeout(() => console.log(event.target), 1000); // won't be null, otherwise if you haven't used event.persist() it would be null.
};

Hier ist ein Live-Beispiel: https://codesandbox.io/s/compassionate-joliot-4eblc?fontsize=14&hidenavigation=1&theme=dark

Alexander Kim
quelle
Warum muss ich immer noch haben , event.persist()mit , console.log(event)aber ich brauche es nicht mit console.log(event.target)?
Isaac Pak
1
Lesen Sie dies: reactjs.org/docs/events.html#event-pooling
Alexander Kim
In diesem Zusammenhang ist es schneller, eine normale Funktion zu verwenden, die 2 Parameter empfängt, als Curry. Sie können einen Benchmark-Test in jsben.ch
ncesar
@ncesar Wie richte ich React in jsben.ch ein? Veröffentlichen Sie Ihren Test plz.
Isaac Pak
@IsaacPak jsben ist ein einfaches Tool zum Testen von Javascript-Codes. Sie platzieren so ziemlich zwei verschiedene Codebeispiele und vergleichen ihre Geschwindigkeit. Sie müssen nicht Ihren gesamten React-Code eingeben, sondern nur eine Funktion, die Ihrer Meinung nach langsamer ist und die Sie testen möchten. Außerdem benutze ich immer jsben.ch und jsbench.me, nur um sicherzugehen. Im clickHandler-Kontext müssten Sie einige Codes verspotten. Wie let event;also ist es ein nicht definierte Fehler werfen würde nicht.
Ncesar