React js onClickはメソッドに値を渡すことができません


639

onClickイベント値のプロパティを読みたいのですが。しかし、それをクリックすると、コンソールに次のようなものが表示されます。

SyntheticMouseEvent {dispatchConfig: Object, dispatchMarker: ".1.1.0.2.0.0:1", nativeEvent: MouseEvent, type: "click", target

私のコードは正しく動作しています。実行すると、表示されます{column}が、onClickイベントで取得できません。

私のコード:

var HeaderRows = React.createClass({
  handleSort:  function(value) {
    console.log(value);
  },
  render: function () {
    var that = this;
    return(
      <tr>
        {this.props.defaultColumns.map(function (column) {
          return (
            <th value={column} onClick={that.handleSort} >{column}</th>
          );
        })}
        {this.props.externalColumns.map(function (column) {
          // Multi dimension array - 0 is column name
          var externalColumnName = column[0];
          return ( <th>{externalColumnName}</th>);
        })}
      </tr>
    );
  }
});

onClickReact jsでイベントに値を渡すにはどうすればよいですか?



2
代わりに自分自身を使用することを検討してください。「これ」と同義である必要があるため、これはかなり誤解を招く可能性があります(ただし、実際には重要ではありません)
Dan

bindメソッドとarrowメソッドを使用して、値をOnclickイベントに渡すことができます
Merugu Prashanth

回答:


1286

簡単な方法

矢印関数を使用します。

return (
  <th value={column} onClick={() => this.handleSort(column)}>{column}</th>
);

これhandleSortにより、適切なパラメーターで呼び出す新しい関数が作成されます。

より良い方法

それをサブコンポーネントに抽出します。 レンダーコールでアロー関数を使用する場合の問題は、毎回新しい関数が作成され、不要な再レンダリングが発生することです。

サブコンポーネントを作成する場合、ハンドラーを渡して、引数として小道具を使用できます。これにより、小道具が変更された場合にのみ再レンダリングされます(ハンドラー参照は変更されないため)。

サブコンポーネント

class TableHeader extends Component {
  handleClick = () => {
    this.props.onHeaderClick(this.props.value);
  }

  render() {
    return (
      <th onClick={this.handleClick}>
        {this.props.column}
      </th>
    );
  }
}

主成分

{this.props.defaultColumns.map((column) => (
  <TableHeader
    value={column}
    onHeaderClick={this.handleSort}
  />
))}

Old Easy Way(ES5)

使用.bindして、必要なパラメーターを渡します。

return (
  <th value={column} onClick={that.handleSort.bind(that, column)}>{column}</th>
);

7
あなたのコードのように使用すると、reactは警告を出します。私のコードをonClick = {that.onClick.bind(null、column)}に変更します
user1924375

12
どのようにこれを使用する<a>ために使用するには、イベントを渡す必要がタグpreventDefault()
サイモン・H

38
@SimonHイベントは、を介して渡す引数の後に、最後の引数として渡されますbind
2015年

47
これはパフォーマンスに悪影響はありませんか?レンダリングごとに新しい関数が作成されませんか?
AndrewMcLagan

13
@AndrewMcLaganです。これは、ルールと最もパフォーマンスの高いソリューションを説明するために見つかりました
E. Sundin

140

ここにいい答えがあります。@ Austin Greco(別のコンポーネントを使用する2番目のオプション)に同意しますカレーを使用する
別の方法があります
できることは、パラメーター(ユーザーのパラメーター)を受け入れる関数を作成し、別のパラメーター(この場合はクリックイベント)を受け入れる別の関数を返すことです。その後、あなたはそれを好きなように自由に使うことができます。

ES5:

handleChange(param) { // param is the argument you passed to the function
    return function (e) { // e is the event object that returned

    };
}

ES6:

handleChange = param => e => {
    // param is the argument you passed to the function
    // e is the event object that returned
};

そして、あなたはそれをこのように使うでしょう:

<input 
    type="text" 
    onChange={this.handleChange(someParam)} 
/>

そのような使用法の完全な例を次に示します。

このアプローチは、各レンダリングでの新しいインスタンスの作成を解決しないことに注意してください。
私はこのアプローチがより簡潔で読みやすいので、他のインラインハンドラーよりもこのアプローチが好きです。

編集:
以下のコメントで提案されているように、関数の結果をキャッシュ/メモすることができます。

これは素朴な実装です:


12
これは受け入れられる答えになるはずです。本当に簡単に実装でき、他のコンポーネントを作成したり、別の方法でバインドしたりする必要はありません。ありがとうございました!
Tamb

29
見た目は良くなりますが、パフォーマンスの観点からは、カレーは実際には効果がありません。同じパラメーターを使用してhandleChangeを2回呼び出すと、JSエンジンが2つの関数を取得するため、たとえ同じことを行っていても、別々のオブジェクトと見なされます。 。したがって、再レンダリングは引き続き可能です。パフォーマンスのために、handleChangeの結果をキャッシュしてパフォーマンスを向上させる必要があります。いいねhandleChange = param => cache[param] || (e => { // the function body })
travellingprog 2017

6
@travellingprogからのアドバイスを満たす場合、これは完璧な答えです
llioor

2
誰かがリンクを提供したり、このキャッシュメカニズムがどのように機能するかを説明したりできますか?ありがとう。
Sadok Mtir

2
美しく清楚!
Hatem Alimam 2018

117

現在、ES6では、更新された回答を使用できると思います。

return (
  <th value={column} onClick={()=>this.handleSort(column)} >{column}</th>
);

基本的に、(知らない人のために)onClick関数が渡されることを期待してbindいるので、関数のコピーを作成するので機能します。代わりに、必要な関数を呼び出すだけの矢印関数式を渡し、を保持できthisます。renderReactでメソッドをバインドする必要はないはずですが、何らかの理由でthisコンポーネントメソッドの1つを失う場合は、次のようにします。

constructor(props) {
  super(props);
  this.myMethod = this.myMethod.bind(this);
}

10
render()Reactによって呼び出されるため、バインドする必要はありません。どちらかとbind言えば、イベントハンドラが必要であり、矢印を使用していない場合のみです。
Dan Abramov

1
@DanAbramov私はあなたが正しいと思いますが、念のために含めました-暗黙的にバインディングレンダリングを奨励しない例で更新しました。
aikeru 2016年

3
それは渡すこともお勧めします注意propsするsuper()か、this.props混乱得ることができますコンストラクタ時に定義されていないことになります。
Dan Abramov

2
何を達成するために?機能コンポーネント内にハンドラーを定義して渡すことができます。これはレンダリングごとに異なる関数になるため、プロファイラーでパフォーマンスの問題が発生すると判断した場合(実際にこれに確信がある場合のみ)、代わりにクラスの使用を検討してください。
Dan Abramov

1
@ me-meはい、そしてBabelで最先端のJavaScriptをオプトインする場合はfoo = () => {...}、次のようにクラスのプロパティを宣言し、レンダリングで参照する<button onClick={this.foo}...だけで、このようにバベルを使用する場合、矢印関数を含める唯一の理由であるIMO、 render()メソッドのスコープにのみ存在する変数をキャプチャしたい場合です(イベントは単に渡され、適用されません)。
-aikeru

73

[[ コメントでこれリンクするための@ E.Sundinへのh / t ]

上位の回答(無名関数またはバインディング)はmap()機能しますが、関数によって生成されるすべてのインスタンスのイベントハンドラーのコピーを作成するため、最もパフォーマンスが高くありません。

これは、ESLint-plugin-reactからそれを行うための最適な方法の説明です。

アイテムのリスト

レンダリングでのバインドの一般的な使用例は、リストをレンダリングするときに、リストアイテムごとに個別のコールバックを持つことです。

const List = props => (
      <ul>
        {props.items.map(item =>
          <li key={item.id} onClick={() => console.log(item.id)}>
            ...
          </li>
        )}
      </ul>
    );

このようにするのではなく、繰り返しセクションを独自のコンポーネントにプルします。

const List = props => (
      <ul>
        {props.items.map(item =>
          <ListItem 
            key={item.id} 
            item={item} 
            onItemClick={props.onItemClick} // assume this is passed down to List
           />
        )}
      </ul>
    );


const ListItem = props => {
  const _onClick = () => {
    console.log(props.item.id);
  }
    return (
      <li onClick={_onClick}>
        ...
      </li>
    );

});

これにより、すべてのレンダリングで(バインド呼び出しを介して)新しい関数を作成する必要がなくなるため、レンダリングが高速化されます。


reactはそれらの関数をcall / applyで呼び出し、内部でバインドし、内部でbindを使用しないようにしますか?
aikeru

1
ステートレスコンポーネントを使用してこれを行う方法はありますか?
カルロスマルティネス

2
@CarlosMartinezよろしくお願いします。例を更新しました。そもそもステートレス機能コンポーネント(SFC)であるはずです。通常、コンポーネントでを使用しない場合はthis.state、SFCと安全に交換できます。
ブランドン、

3
うーん、これはもっとパフォーマンスが良い方法がわかりませんか?ListItem関数は毎回呼び出されないため、_onClick関数はレンダリングごとに作成されます。
マティアスペッターヨハンソン

1
私はここのエキスパートにはほど遠いですが、私が理解しているように、「正しい」パターンでは、ハンドラーのインスタンスは1つしかなく、コンポーネントのインスタンスが呼び出すインスタンスのプロップが渡されます。バインドの例(「間違った」パターン)では、インスタンス化されたコンポーネントごとにハンドラーのインスタンスが1つあります。これは、同じ関数を30回書き込んだり、1回書き込んだり、必要に応じて呼び出したりするのと同じようなメモリです。
ブランドン、

25

これは私のアプローチです、それがどれほど悪いかわかりません、コメントしてください

クリック可能な要素

return (
    <th value={column} onClick={that.handleSort} data-column={column}>   {column}</th>
);

その後

handleSort(e){
    this.sortOn(e.currentTarget.getAttribute('data-column'));
}

これは私が考えていたアプローチです。少しハックに感じますが、新しいコンポーネントの作成を避けます。getAttributeが別のコンポーネントへのプルと比較してパフォーマンス面で良いか悪いかはわかりません。
kamranicus 2017年

2
とてもシンプルなので良い解決策だと思います。ただし、文字列値でのみ機能します。オブジェクトが必要な場合は機能しません。
ステファンL

オブジェクトの場合、実行する必要がありencodeURIComponent(JSON.stringify(myObj))、次に解析する必要がありますJSON.parse(decodeURIComponent(myObj))。関数の場合、これはevalまたはnew Function()なしでは機能しないと確信しています。どちらも回避する必要があります。これらの理由により、React / JSでデータを渡すためにデータ属性を使用しません。
Solvitieg

私はこれを頻繁に使用せず、マイナーなものにのみ使用することを付け加えたいと思います。しかし、通常は単にコンポーネントを作成し、データを小道具としてそれに渡します。次に、その新しいコンポーネント内のクリックを処理するか、onClick関数をコンポーネントに渡します。ブランドンの回答で説明されているように
サンティアゴラミレス

1
データセットには、最新のブラウザー(IE11を含む)で次のように直接アクセスできます:e.currentTarget.dataset.column
gsziszi

17

この例はあなたの例と少し異なるかもしれません。しかし、これがあなたがこの問題に対して持つことができる最良の解決策であることを保証することができます。パフォーマンスの問題がないソリューションを何日も検索しました。そしてついにこれを思いついた。

class HtmlComponent extends React.Component {
  constructor() {
    super();
    this.state={
       name:'MrRehman',
    };
    this.handleClick= this.handleClick.bind(this);
  }

  handleClick(event) {
    const { param } = e.target.dataset;
    console.log(param);
    //do what you want to do with the parameter
  }

  render() {
    return (
      <div>
        <h3 data-param="value what you wanted to pass" onClick={this.handleClick}>
          {this.state.name}
        </h3>
      </div>
    );
  }
}

更新

パラメータとなるはずのオブジェクトを処理する場合。これを使用JSON.stringify(object)して文字列に変換し、データセットに追加できます。

return (
   <div>
     <h3 data-param={JSON.stringify({name:'me'})} onClick={this.handleClick}>
        {this.state.name}
     </h3>
   </div>
);

1
渡されたデータがオブジェクトの場合、これは機能しません
SlimSim

JSON.stringifyを使用して問題を修正します。@SlimSim。これでうまくいくはずです
hannad rehman '21

この問題にJSON.stringifyを使用する必要がある場合は、おそらく正しい方法ではありません。文字列化のプロセスには多くのメモリが必要です。
KFE 2017年

ほとんどの場合、IDをparamsとして渡し、ソースオブジェクトからそのIDに基づいてオブジェクトの詳細を取得します。そして、なぜそしてどのように多くのメモリを必要とするのか、私はJSON文字列化が遅いことを知っていますが、クリックFnは非同期であり、一度構築されるとdomに影響を与えないか、まったく影響しません
hannad rehman


4

.bindまたはES6に関係しないもう1つのオプションは、ハンドラーで子コンポーネントを使用して、必要な小道具で親ハンドラーを呼び出すことです。次に例を示します(そして、実際の例へのリンクを以下に示します)。

var HeaderRows = React.createClass({
  handleSort:  function(value) {
     console.log(value);
  },
  render: function () {
      var that = this;
      return(
          <tr>
              {this.props.defaultColumns.map(function (column) {
                  return (
                      <TableHeader value={column} onClick={that.handleSort} >
                        {column}
                      </TableHeader>
                  );
              })}
              {this.props.externalColumns.map(function (column) {
                  // Multi dimension array - 0 is column name
                  var externalColumnName = column[0];
                  return ( <th>{externalColumnName}</th>
                  );
              })}
          </tr>);
      )
  }
});

// A child component to pass the props back to the parent handler
var TableHeader = React.createClass({
  propTypes: {
    value: React.PropTypes.string,
    onClick: React.PropTypes.func
  },
  render: function () {
    return (
      <th value={this.props.value} onClick={this._handleClick}
        {this.props.children}
      </th>
    )        
  },
  _handleClick: function () {
    if (this.props.onClick) {
      this.props.onClick(this.props.value);
    }
  }
});

基本的な考え方は、親コンポーネントがonClick関数を子コンポーネントに渡すことです。子コンポーネントはonClick関数を呼び出し、props渡されたもの(およびevent)にアクセスできるためevent、親のonClick関数内で任意の値または他の小道具を使用できます。

ここだデモCodePenのアクションで、この方法を示します。


4

e.preventDefault()呼び出しを含むOPの質問に答える別の試みを行う:

レンダリングされたリンク(ES6

<a href="#link" onClick={(e) => this.handleSort(e, 'myParam')}>

コンポーネント機能

handleSort = (e, param) => {
  e.preventDefault();
  console.log('Sorting by: ' + param)
}

4

私はこれがパーティーにかなり遅れていることを理解していますが、もっと簡単な解決策が多くのユースケースを満たすことができると思います:

    handleEdit(event) {
        let value = event.target.value;
    }

    ...

    <button
        value={post.id}
        onClick={this.handleEdit} >Edit</button>

data-属性も使用できると思います。

シンプル、セマンティック。


4

このような関数を作成するだけです

  function methodName(params) {
    //the thing  you wanna do
  }

必要な場所にそれを呼び出します

<Icon onClick = {()=> {methodName(theParamsYouwantToPass); }} />


3

を使用している場合は、簡単に実行できますES6

export default class Container extends Component {
  state = {
    data: [
        // ...
    ]
  }

  handleItemChange = (e, data) => {
      // here the data is available 
      // ....
  }
  render () {
     return (
        <div>
        {
           this.state.data.map((item, index) => (
              <div key={index}>
                  <Input onChange={(event) => this.handItemChange(event, 
                         item)} value={item.value}/>
              </div>
           ))
        }
        </div>
     );
   }
 }

3

以下で説明するように、countをメインコンポーネントからサブコンポーネントにパラメーターとして渡すことで、オブジェクトからのshow total countを実装します。

ここにMainComponent.jsがあります

import React, { Component } from "react";

import SubComp from "./subcomponent";

class App extends Component {

  getTotalCount = (count) => {
    this.setState({
      total: this.state.total + count
    })
  };

  state = {
    total: 0
  };

  render() {
    const someData = [
      { name: "one", count: 200 },
      { name: "two", count: 100 },
      { name: "three", count: 50 }
    ];
    return (
      <div className="App">
        {someData.map((nameAndCount, i) => {
          return (
            <SubComp
              getTotal={this.getTotalCount}
              name={nameAndCount.name}
              count={nameAndCount.count}
              key={i}
            />
          );
        })}
        <h1>Total Count: {this.state.total}</h1>
      </div>
    );
  }
}

export default App;

そしてここに SubComp.js

import React, { Component } from 'react';
export default class SubComp extends Component {

  calculateTotal = () =>{
    this.props.getTotal(this.props.count);
  }

  render() {
    return (
      <div>
        <p onClick={this.calculateTotal}> Name: {this.props.name} || Count: {this.props.count}</p>
      </div>
    )
  }
};

上記を実装してみると、DOMメソッドのreactjsでパスパラメータがどのように機能するかを正確に把握できます。


3

ここで受け入れられた回答に基づいて、この目的で再利用できるラッパーコンポーネントを作成しました。ただし、文字列を渡すだけでよい場合は、データ属性を追加してe.target.datasetから読み取るだけです(他の人が提案したように)。デフォルトでは、ラッパーは関数であるプロップにバインドし、「on」で始まり、他のすべてのイベント引数の後にデータプロップを呼び出し元に自動的に返します。パフォーマンスについてはテストしていませんが、自分でクラスを作成しないようにする機会があり、次のように使用できます。

const DataButton = withData('button')
const DataInput = withData('input');

またはコンポーネントおよび機能用

const DataInput = withData(SomeComponent);

またはご希望の場合

const DataButton = withData(<button/>)

コンテナーの外側(インポートの近く)を宣言します

コンテナでの使用方法は次のとおりです。

import withData from './withData';
const DataInput = withData('input');

export default class Container extends Component {
    state = {
         data: [
             // ...
         ]
    }

    handleItemChange = (e, data) => {
        // here the data is available 
        // ....
    }

    render () {
        return (
            <div>
                {
                    this.state.data.map((item, index) => (
                        <div key={index}>
                            <DataInput data={item} onChange={this.handleItemChange} value={item.value}/>
                        </div>
                    ))
                }
            </div>
        );
    }
}

これがラッパーコード「withData.js:

import React, { Component } from 'react';

const defaultOptions = {
    events: undefined,
}

export default (Target, options) => {
    Target = React.isValidElement(Target) ? Target.type : Target;
    options = { ...defaultOptions, ...options }

    class WithData extends Component {
        constructor(props, context){
            super(props, context);
            this.handlers = getHandlers(options.events, this);        
        }

        render() {
            const { data, children, ...props } = this.props;
            return <Target {...props} {...this.handlers} >{children}</Target>;
        }

        static displayName = `withData(${Target.displayName || Target.name || 'Component'})`
    }

    return WithData;
}

function getHandlers(events, thisContext) {
    if(!events)
        events = Object.keys(thisContext.props).filter(prop => prop.startsWith('on') && typeof thisContext.props[prop] === 'function')
    else if (typeof events === 'string')
        events = [events];

    return events.reduce((result, eventType) => {
        result[eventType] = (...args) => thisContext.props[eventType](...args, thisContext.props.data);
        return result;
    }, {});
}

2

JSX onClickイベントでこれについて3つ以下の提案があります-

  1. 実際には、コードで.bind()やArrow関数を使用する必要はありません。コードで簡単に使用できます。

  2. onClickイベントをth(またはul)からtr(またはli)に移動して、パフォーマンスを向上させることもできます。基本的に、n li要素にはn個の「イベントリスナー」があります。

    So finally code will look like this:
    <ul onClick={this.onItemClick}>
        {this.props.items.map(item =>
               <li key={item.id} data-itemid={item.id}>
                   ...
               </li>
          )}
    </ul>

    // 以下に示すようitem.idonItemClickメソッドにアクセスできます:

    onItemClick = (event) => {
       console.log(e.target.getAttribute("item.id"));
    }
  3. 上記のListItemとListのReactコンポーネントを個別に作成する方法に同意します。このmakeコードは適切に見えますが、liが1000ある場合、1000のイベントリスナーが作成されます。イベントリスナーが多くないようにしてください。

    import React from "react";
    import ListItem from "./ListItem";
    export default class List extends React.Component {
    
        /**
        * This List react component is generic component which take props as list of items and also provide onlick
        * callback name handleItemClick
        * @param {String} item - item object passed to caller
        */
        handleItemClick = (item) => {
            if (this.props.onItemClick) {
                this.props.onItemClick(item);
            }
        }
    
        /**
        * render method will take list of items as a props and include ListItem component
        * @returns {string} - return the list of items
        */
        render() {
            return (
                <div>
                  {this.props.items.map(item =>
                      <ListItem key={item.id} item={item} onItemClick={this.handleItemClick}/>
                  )}
                </div>
            );
        }
    
    }
    
    
    import React from "react";
    
    export default class ListItem extends React.Component {
        /**
        * This List react component is generic component which take props as item and also provide onlick
        * callback name handleItemClick
        * @param {String} item - item object passed to caller
        */
        handleItemClick = () => {
            if (this.props.item && this.props.onItemClick) {
                this.props.onItemClick(this.props.item);
            }
        }
        /**
        * render method will take item as a props and print in li
        * @returns {string} - return the list of items
        */
        render() {
            return (
                <li key={this.props.item.id} onClick={this.handleItemClick}>{this.props.item.text}</li>
            );
        }
    }

1
渡す必要のあるデータがオブジェクトの場合、これは機能しません。属性は文字列でのみ機能します。また、get属性を介してdomから読み取ることは、おそらくより高価な操作です。
SlimSim 2017

2

onclickイベント値をメソッドに渡すためのコードを2つの方法で追加しました。1。bindメソッドの使用2. arrow(=>)メソッドの使用 メソッドhandlesort1とhandlesortを参照してください

var HeaderRows  = React.createClass({
    getInitialState : function() {
      return ({
        defaultColumns : ["col1","col2","col2","col3","col4","col5" ],
        externalColumns : ["ecol1","ecol2","ecol2","ecol3","ecol4","ecol5" ],

      })
    },
    handleSort:  function(column,that) {
       console.log(column);
       alert(""+JSON.stringify(column));
    },
    handleSort1:  function(column) {
       console.log(column);
       alert(""+JSON.stringify(column));
    },
    render: function () {
        var that = this;
        return(
        <div>
            <div>Using bind method</div>
            {this.state.defaultColumns.map(function (column) {
                return (
                    <div value={column} style={{height : '40' }}onClick={that.handleSort.bind(that,column)} >{column}</div>
                );
            })}
            <div>Using Arrow method</div>

            {this.state.defaultColumns.map(function (column) {
                return (
                    <div value={column} style={{height : 40}} onClick={() => that.handleSort1(column)} >{column}</div>

                );
            })}
            {this.state.externalColumns.map(function (column) {
                // Multi dimension array - 0 is column name
                var externalColumnName = column;
                return (<div><span>{externalColumnName}</span></div>
                );
            })}

        </div>);
    }
});

2

以下は、onClickイベントに値を渡す例です。

私はes6構文を使用しました。クラスコンポーネントでは、arrow関数は自動的にバインドしないため、コンストラクターで明示的にバインドすることを覚えておいてください。

class HeaderRows extends React.Component {

    constructor(props) {
        super(props);
        this.handleSort = this.handleSort.bind(this);
    }

    handleSort(value) {
        console.log(value);
    }

    render() {
        return(
            <tr>
                {this.props.defaultColumns.map( (column, index) =>
                    <th value={ column } 
                        key={ index } 
                        onClick={ () => this.handleSort(event.target.value) }>
                        { column }
                    </th>
                )}

                {this.props.externalColumns.map((column, index)  =>
                    <th value ={ column[0] }
                        key={ index }>
                        {column[0]}
                    </th>
                )}
            </tr>
         );
    }
}

2

メソッドをReactのクラスインスタンスにバインドする必要があると思います。コンストラクタを使用してすべてのメソッドをReactにバインドする方が安全です。パラメーターをメソッドに渡す場合、最初のパラメーターはメソッドの 'this'コンテキストをバインドするために使用されるため、メソッド内の値にアクセスできません。


2
1. You just have to use an arrow function in the Onclick event like this: 

<th value={column} onClick={() => that.handleSort(theValue)} >{column}</th>

2.Then bind this in the constructor method:
    this.handleSort = this.handleSort.bind(this);

3.And finally get the value in the function:
  handleSort(theValue){
     console.log(theValue);
}


2
class TableHeader extends Component {
  handleClick = (parameter,event) => {
console.log(parameter)
console.log(event)

  }

  render() {
    return (
      <button type="button" 
onClick={this.handleClick.bind(this,"dataOne")}>Send</button>
    );
  }
}

4
このコードは問題を解決する可能性がありますが、説明を含めると、投稿の品質を向上させるのに役立ちます。あなたは将来の読者のための質問に答えていることを覚えておいてください、そしてそれらの人々はあなたのコード提案の理由を知らないかもしれません。
Shree

2

この質問にはどこからともなく出てきます.bindが、私はトリックを行うと思います。以下のサンプルコードを見つけてください。

const handleClick = (data) => {
    console.log(data)
}

<button onClick={handleClick.bind(null, { title: 'mytitle', id: '12345' })}>Login</button>

1

アロー機能を使用する:

ステージ2をインストールする必要があります。

npm install babel-preset-stage-2:

class App extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            value=0
        }
    }

    changeValue = (data) => (e) => {
        alert(data);  //10
        this.setState({ [value]: data })
    }

    render() {
        const data = 10;
        return (
            <div>
                <input type="button" onClick={this.changeValue(data)} />
            </div>
        );
    }
}
export default App; 

0

これを処理するには3つの方法があります:-

  1. 次のようにメソッドをコンストラクタにバインドします:

    export class HeaderRows extends Component {
       constructor() {
           super();
           this.handleSort = this.handleSort.bind(this);
       }
    }
  2. 次のように作成しながら、矢印関数を使用します:-

    handleSort = () => {
        // some text here
    }
  3. 3番目の方法はこれです:-

    <th value={column} onClick={() => that.handleSort} >{column}</th>

0

次のようなコードを使用できます。

<th value={column} onClick={(e) => that.handleSort(e, column)} >{column}</th>

ここで、eはイベントオブジェクト用preventDefault()で、ハンドル関数などでイベントメソッドを使用する場合や、などのターゲット値または名前を取得する場合に使用しますe.target.name


0

タグの属性としてparamを渡す解決策は非常に合理的であることがわかりました。

ただし、制限があります。

  • リストアイテムに他のタグがある場合、正しく機能しません(そのため、event.targetは意図したものと異なる場合があります)
  • パラメータは文字列のみにすることができます。シリアル化と逆シリアル化が必要です。

それが私がこのライブラリを思いついた理由です:react-event-param

それ:

  • 必要なときにいつでも親で必要な属性を検索することにより、子供の問題を解決します
  • パラメータを自動的にシリアライズおよびデシリアライズします
  • 設定と取得のロジックをカプセル化します。パラメータ名をいじる必要はありません

使用例:

import { setEventParam, getEventParam } from "react-event-param";

class List extends Component {
  onItemClick = e => {
    const index = getEventParam(e.target);
    // Do something with index
  };

  render() {
    return (
      <ul>
        {this.props.items.map((itemText, index) => (
          <li
            key={index}
            {...setEventParam(index)}
            onClick={this.onItemClick}
          >
            {{ itemText }}
          </li>
        ))}
      </ul>
    );
  }
}

export default List;

0

パフォーマンスに関する多くの考慮事項がありましたが、すべてが孤立しています。
このハンドラーの問題は、プロップで名前を付けることができない引数を組み込むために、それらをカレーする必要があることです。
つまり、コンポーネントには、クリック可能な要素ごとにハンドラーが必要です。いくつかのボタンについては、これは問題ではないということに同意しましょう。
この問題は、数十列と数千行の表形式データを処理するときに発生します。そこで、あなたはそれだけ多くのハンドラを作成することの影響に気づきます。

実際は、私は1つだけ必要です。
ハンドラーをテーブルレベル(またはULまたはOL ...)に設定し、クリックが発生したときに、イベントオブジェクトでこれまで利用可能なデータを使用して、クリックされたセルがどれであるかを確認できます。

nativeEvent.target.tagName
nativeEvent.target.parentElement.tagName 
nativeEvent.target.parentElement.rowIndex
nativeEvent.target.cellIndex
nativeEvent.target.textContent

tagnameフィールドを使用して、有効な要素でクリックが発生したことを確認します。たとえば、フッターのクリックを無視します。
rowIndexおよびcellIndexは、クリックされたセルの正確な位置を示します。
Textcontentは、クリックされたセルのテキストです。

このようにして、セルのデータをハンドラーに渡す必要がなくなり、セルラーでセルフサービスできます。
さらに多くのデータ、表示されないデータが必要な場合は、データセット属性または非表示要素を使用できます。
いくつかの単純なDOMナビゲーションがあれば、すべて手元にあります。
これは、PCの方がはるかに使いにくいため、HTMLで使用されています。


0

イベントハンドラーでパラメーターを渡す方法はいくつかありますが、いくつかは以下のとおりです。

アロー関数を使用して、イベントハンドラーをラップし、パラメーターを渡すことができます。

<button onClick={() => this.handleClick(id)} />

上記の例は、呼び出しと同等.bindです。または、明示的にbind を呼び出すことができます。

<button onClick={this.handleClick.bind(this, id)} />

これらの2つのアプローチとは別に、カレー関数として定義されている関数に引数を渡すこともできます。

handleClick = (id) => () => {
    console.log("Hello, your ticket number is", id)
};

<button onClick={this.handleClick(id)} />

-1

クロージャーを使用すると、クリーンなソリューションになります:

<th onClick={this.handleSort(column)} >{column}</th>

handleSort関数は、値の列が既に設定されている関数を返します

handleSort: function(value) { 
    return () => {
        console.log(value);
    }
}

ユーザーがthをクリックすると、無名関数が正しい値で呼び出されます。

例:https : //stackblitz.com/edit/react-pass-parameters-example


-2

単純な変更が必要です:

使用する <th value={column} onClick={that.handleSort} >{column}</th>

の代わりに <th value={column} onClick={that.handleSort} >{column}</th>

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.