ReactonClick-パラメータを使用してイベントを渡します


99

パラメータなし

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

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

パラメータ付き

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

取得したいevent。どうすれば入手できますか?

回答:


178

これを試して:

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

そしてあなたの機能では:

function clickMe(event, someParameter){
     //do with event
}

3
これにより、eslintエラーが発生しました(eslint.org/docs/rules/arrow-parens.html)。私が行ったことは、関数パラメーターを括弧でonClick={(e) => { this.clickMe(e, someparameter) }}
囲むことでした

1
はい@kretzm中かっこを指定しない場合、1行の場合は戻り式として機能します。それ以外の場合は、中かっこを使用して関数本体としてラップする必要があります。
Jyothi Babu Araja 2017

4
推奨されない構文であることを付け加えたいと思います。reactjsのドキュメントから:この構文の問題は、ボタンがレンダリングされるたびに異なるコールバックが作成されることです。ほとんどの場合、これで問題ありません。ただし、このコールバックが小道具として下位コンポーネントに渡された場合、それらのコンポーネントは追加の再レンダリングを行う可能性があります。この種のパフォーマンスの問題を回避するために、通常、コンストラクターでバインドするか、クラスフィールド構文を使用することをお勧めします。詳細情報reactjs.org
northernwind

1
@ビクター。はい、その通りです。ただし、コールバック内に親のコンテキストが必要な場合は、レンダリングごとに異なるコールバックを設定する必要があります。実際、それはトレードオフだと思います。
Jyothi BabuAraja18年

@JyothiBabuAraja最善の解決策はdata-*、HTML5の属性を利用することだと思います。詳細については、以下の私の回答を参照してください。
ハリーチャン

37

ES6を使用すると、次のように短い方法で実行できます。

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

そしてそれを使用してください:

<button onClick={clickMe(someParameter)} />

これにより、新しいコールバックの問題の作成も解決されますか?stackoverflow.com/questions/42597602/...
大谷酒造

1
これに加えて、複数のパラメータを送信できます。constのclickMe =(パラメーター1、パラメーター)=>(イベント)=> {//実行(Do)何か}
アフラ・マズダー

1
また、あなたのコンポーネントが搭載されているときに発生する。この一つは、あなたのコードは次のようになりますonClick={(e) => clickMe(someParameter)(e)}
アレクサンダーキム

clickMeだけの場合と同様に、イベントをパラメータとして定義しなくても、イベントを破棄できます。
ミンカ

これをありがとう。できます。しかし、なぜconst clickMe = (parameter) => (event) => {...} 代わりにあるのconst clickMe = (parameter) => {...}ですか?
zrna

17

解決策1

function clickMe(parameter, event){
}

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

解決策2 解決策1では、矢印関数を使用するよりも、バインド関数を使用する方が適切と見なされます。イベントパラメーターはハンドラー関数の最後のパラメーターである必要があることに注意してください。

function clickMe(parameter, event){
}

<button onClick={this.clickMe.bind(this, someParameter)}></button>

ソリューション#2の最後のものであるイベントパラメータの+1。私が間違っていたことに気付くために永遠に私を連れて行きました、私はドキュメントのどこかで理由を逃したに違いありません。
abelito

5

新しいコールバックの作成の問題を完全に解決するにはdata-*、HTML5の属性を利用することがIMOの最善の解決策です。結局のところ、サブコンポーネントを抽出してパラメーターを渡しても、それでも新しい関数が作成されます。

例えば、

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

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

属性の使用については、https://developer.mozilla.org/en-US/docs/Learn/HTML/Howto/Use_data_attributesを参照してくださいdata-*


私はこのアプローチが好きです。シンプルでクリーン
marknt 1520年

5

ES6の例でカリー化

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

ハンドラーを切り替えるボタン:

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

イベントオブジェクトなしでこの関数式を呼び出したい場合は、次のように呼び出します。

clickHandler(1)();

また、reactは合成イベント(ネイティブイベントのラッパー)を使用するため、イベントプーリングがあります。つまり、eventオブジェクトを非同期で使用する場合は、次を使用する必要があります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.
};

実例は次のとおりです:https//codesandbox.io/s/compassionate-joliot-4eblc?fontsize = 14&hidenavigation = 1&theme = dark


なぜ私はまだ持っている必要がありますevent.persist()console.log(event)、私はとそれを必要としませんかconsole.log(event.target)
アイザックパック

1
これを読んでください:reactjs.org/docs/events.html#event-pooling
AlexanderKim20年

このコンテキストでは、カリー化よりも2つのパラメーターを受け取る通常の関数を使用する方が高速です。あなたはjsben.chでベンチマークテストを実行することができます
ncesar

@ncesar jsben.chでReactをどのように設定しますか?テストplzを投稿してください。
アイザックパック

@IsaacPak jsbenは、JavaScriptコードをテストするためのシンプルなツールです。コードの2つの異なるサンプルを配置し、それらの速度を比較します。Reactコード全体を配置する必要はありません。速度が遅く、テストしたい関数だけを配置する必要があります。また、念のため、常にjsben.chとjsbench.meを使用しています。clickHandlerコンテキストでは、いくつかのコードをモックする必要があります。そのようにlet event;、それは未定義のエラーをスローしません。
ncesar
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.