React js onClick, yönteme değer iletemiyor


638

OnClick olay değeri özelliklerini okumak istiyorum. Ama üzerine tıkladığımda, konsolda şöyle bir şey görüyorum:

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

Kodum düzgün çalışıyor. Çalıştığımda görebiliyorum {column}ama onClick olayında alamıyorum.

Kodum:

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 olayına nasıl bir değer iletebilirim ?



2
bunun yerine kendini kullanmayı düşünün. "Bu" ile eşanlamlı olması gerektiği için oldukça yanıltıcıdır (her ne kadar kendi başına önemli değil)
Dan

Bind yöntemini ve ok yöntemini kullanarak değeri Onclick etkinliğine
geçirebiliriz

1
bu örneğe göz
atın Reats js'de

Yanıtlar:


1285

Kolay yol

Bir ok işlevi kullanın:

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

Bu handleSort, doğru parametrelerle çağrılan yeni bir işlev yaratacaktır .

Daha iyi yol

Bir alt bileşene ayıklayın. Oluşturma çağrısında bir ok işlevi kullanmayla ilgili sorun, her seferinde yeni bir işlev oluşturacağı ve sonuçta gereksiz yeniden oluşturmalara neden olacağıdır.

Bir alt bileşen oluşturursanız, işleyiciyi geçirebilir ve bağımsız değişkenler olarak props komutlarını kullanabilirsiniz.

Alt bileşen

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

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

Ana bileşen

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

Eski Kolay Yol (ES5)

İstediğiniz .bindparametreyi iletmek için kullanın :

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

7
tepki gibi kodunuzu kullandığınızda uyarı verir. Kodumu onClick = {that.onClick.bind (null, sütun)} olarak değiştiriyorum
user1924375

12
Bunu kullanmak <a>için etkinliği geçmeniz gereken bir etiketle nasıl kullanırsınızpreventDefault()
Simon H

38
@SimonH Etkinlik, geçtiğiniz argümanlardan sonra son argüman olarak iletilir bind.
leke

47
Bu performans için kötü değil mi? her render yeni bir işlev oluşturulmayacak mı?
AndrewMcLagan

13
@AndrewMcLagan Öyle. Bunu kuralı ve en performanslı çözümü tanımlamak için buldum .
E. Sundin

140

Orada güzel cevaplar burada, ve ben @Austin Greco (ayrı bileşenleri ile ikinci seçenek) ile kabul
i gibi başka bir yolu yoktur, -işlemden .
Yapabileceğiniz şey, bir parametreyi kabul eden bir işlev (parametreniz) oluşturmak ve başka bir parametreyi kabul eden başka bir işlev (bu durumda click olayı) döndürmektir. o zaman onunla istediğin şeyi yapmakta özgürsün.

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
};

Ve bunu şu şekilde kullanacaksınız:

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

İşte böyle bir kullanıma tam bir örnek:

Bu yaklaşımın her oluşturmada yeni bir örnek oluşturmayı çözmediğini unutmayın.
Bu yaklaşımı diğer satır içi işleyicilere göre seviyorum, çünkü bu benim görüşüme göre daha özlü ve okunabilir.

Düzenle:
Aşağıdaki yorumlarda önerildiği gibi, işlevin sonucunu önbelleğe alabilir / kaydedebilirsiniz.

İşte naif bir uygulama:


12
Bu kabul edilen cevap olmalı. GERÇEKTEN uygulanması kolaydır ve başka bileşenler oluşturmanıza veya farklı bir şekilde bağlamanıza gerek yoktur. Teşekkür ederim!
Tamb

29
Daha iyi görünüyor, ancak performans açısından bakıldığında, körelme gerçekten yardımcı olmuyor, çünkü handleChange'ı iki kez çağırırsanız, aynı parametreyle, aynı motoru yapsalar bile JS motorunun ayrı nesneler olarak kabul ettiği iki işlev elde edersiniz . Yani hala bir yeniden render elde edersiniz. Performans uğruna, performans avantajı elde etmek için handleChange sonuçlarını önbelleğe almanız gerekir. BeğenhandleChange = param => cache[param] || (e => { // the function body })
travellingprog

6
@Travellingprog
llioor

2
Herhangi bir bağlantı sağlayabilir veya bu önbellekleme mekanizmasının nasıl çalıştığını açıklayabilir mi? Teşekkürler.
Sadok Mtir

2
Güzel ve temiz!
Hatem Alimam

117

Günümüzde ES6 ile güncellenmiş bir cevap kullanabileceğimizi düşünüyorum.

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

Temel olarak, (bilmeyenler için) onClickkendisine aktarılan bir işlev beklediğinden, bir işlevin bindbir kopyasını oluşturduğu için çalışır. Bunun yerine, istediğimiz işlevi çağıran ve koruyan bir ok işlevi ifadesini iletebiliriz this. renderReact içindeki yöntemi asla bağlamamalısınız, ancak herhangi bir nedenle thisbileşen yöntemlerinizden birinde kaybediyorsanız :

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

10
Asla bağlamanıza gerek yoktur render()çünkü React tarafından çağrılır. Bir şey varsa bind, olay işleyicilerine ve yalnızca ok kullanmadığınızda gerekir.
Dan Abramov

1
@DanAbramov Doğru olduğunu düşünüyorum, ancak her ihtimale karşı - bağlayıcı render teşvik dolaylı bir örnek ile güncellenen dahil.
aikeru

3
Geçmesi için de en iyisi Not propsiçin super()veya this.propskafa karıştırıcı alabilirsiniz yapıcı sırasında tanımsız olacaktır.
Dan Abramov

2
Neyi başarmak için? İşlevsel bileşenin içinde bir işleyici tanımlayabilir ve iletebilirsiniz. Her render farklı bir işlev olacaktır, bu yüzden size bir profilerle mükemmel sorunlar verdiğini belirlediyseniz (ve sadece bundan eminseniz!), Bunun yerine bir sınıf kullanmayı düşünün.
Dan Abramov

1
@ me-me Evet ve eğer Babel'de kanayan kenar JavaScript'e katılmayı seçerseniz, sınıfınızdaki özellikleri sadece bildirmeniz foo = () => {...}ve daha sonra <button onClick={this.foo}...babil'i bu şekilde kullanırsanız, IMO, yalnızca render () yöntemi kapsamında var olan bir değişkeni yakalamak istiyorsanız (olaylar aktarılabilir ve uygulanamaz).
aikeru

73

[[ bir yorumda bunu bağladığı için @ E.Sundin'e h / t ]

Üst yanıt (anonim işlevler veya ciltleme) işe yarayacaktır, ancak map()işlev tarafından oluşturulan her örnek için olay işleyicisinin bir kopyasını oluşturduğundan en performanslı değildir .

Bu, ESLint-eklenti tepkisinden bunu yapmanın en iyi yolunun bir açıklamasıdır :

Ürün Listeleri

Oluşturmada bağlamanın yaygın bir kullanım durumu, bir liste oluşturulurken, liste öğesi başına ayrı bir geri arama yapılmasıdır:

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

Bu şekilde yapmak yerine, tekrarlanan bölümü kendi bileşenine çekin:

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>
    );

});

Bu, her renderde yeni işlevler (ciltleme çağrıları aracılığıyla) yaratma ihtiyacını ortadan kaldırdığı için oluşturmayı hızlandırır.


Tepki bu işlevleri kaputun altında arama / uygulama, ardından bağlama ile çağırıyor ve dahili olarak bağlanmaktan kaçınıyor mu?
aikeru

1
Bunu vatansız bir bileşen kullanarak yapmanın bir yolu var mı?
Carlos Martinez

2
@CarlosMartinez iyi göz, örneği güncelledim - ilk etapta vatansız fonksiyonel bileşenler (SFC) olmalıydı. Genellikle, bir bileşen hiç kullanmadıysa this.state, bir SFC ile güvenle değiştirebilirsiniz.
Brandon

3
Hmm, bunun nasıl daha performanslı olduğunu anlamıyorum? ListItem işlevi her seferinde çağrılmayacak ve böylece her renderde _onClick işlevi oluşturulacak.
Mattias Petter Johansson

1
Burada bir uzmandan çok uzakım, ama anladığım kadarıyla, 'doğru' desende, işleyicinin sadece bir örneği var ve bileşenin hangi örneği onu çağırırsa onu destekledi. Bağlama örneğinde (yani, 'yanlış' desen), her somutlaştırılmış bileşen için işleyicinin bir örneği vardır. Aynı işlevi otuz kez bir kez yazmanın ve gerektiğinde çağırmanın bellek eşdeğeri.
Brandon

25

Bu benim yaklaşımım, ne kadar kötü olduğundan emin değilim, lütfen yorum yap

Tıklanabilir öğede

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

ve sonra

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

Bu düşündüğüm bir yaklaşım, biraz acayip geliyor ama yeni bir bileşen oluşturmaktan kaçınıyor. GetAttribute'un ayrı bir bileşene çekmeye kıyasla daha iyi veya daha kötü olup olmadığından emin değilim.
Mart'ta kamranicus

2
Bence bu iyi bir çözüm çünkü çok basit. Ancak yalnızca dize değerleriyle çalışır, bir nesne istiyorsanız işe yaramaz.
Stephane L

Bir nesne için yapmanız encodeURIComponent(JSON.stringify(myObj)), sonra ayrıştırmanız gerekir JSON.parse(decodeURIComponent(myObj)). Fonksiyonlar için eminim bu eval veya yeni Function () olmadan çalışmayacak, her ikisi de kaçınılmalıdır. Bu nedenlerden dolayı React / JS'de veri iletmek için veri özniteliklerini kullanmıyorum.
Solvitieg

Eklemek istiyorum, bunu sık sık kullanmıyorum ve sadece küçük şeyler için. Ama genellikle sadece bir bileşen oluşturuyorum ve verileri ona sahne olarak iletiyorum. Ardından, yeni bileşenin içindeki tıklamayı işleyin veya bileşene bir onClick işlevi iletin. Brandon cevabında açıklandığı gibi
Santiago Ramirez

1
veri kümesine bu yolla doğrudan modern tarayıcılarda (IE11 dahil) erişilebilir: e.currentTarget.dataset.column
gsziszi

17

bu örnek sizinkinden biraz farklı olabilir. ancak bunun bu sorun için sahip olabileceğiniz en iyi çözüm olduğunu garanti edebilirim. performans sorunu olmayan bir çözüm için günlerce aradım. ve sonunda bunu buldum.

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>
    );
  }
}

GÜNCELLEME

eğer parametreler olması gereken nesnelerle uğraşmak istiyorsanız. Kullanabileceğiniz JSON.stringify(object)dizeye kendisine dönüştürmek ve veri kümesine ekleyin.

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

1
geçen veri bir nesne olduğunda bu çalışmaz
SlimSim

sorunu gidermek için JSON.stringify komutunu kullanın. @SlimSim. hile yapmak gerekir
hannad rehman

Bu sorun için JSON.stringify kullanmanız gerekiyorsa, muhtemelen doğru yöntem değildir. Diziliş süreci çok fazla hafıza gerektirir.
KFE

çoğu durumda kimliği yalnızca parametreler olarak geçirir ve bu tanıma dayalı nesne ayrıntılarını kaynak nesnenizden alırsınız. ve neden ve nasıl çok fazla bellek alır, JSON stringify yavaş olduğunu biliyorum, ama tıklayın Fn zaman uyumsuz ve bir kez inşa dom üzerinde hiçbir veya 0 etkisi olacak
hannad rehman

6
class extends React.Component {
    onClickDiv = (column) => {
        // do stuff
    }
    render() {
        return <div onClick={() => this.onClickDiv('123')} />
    }
}

2
Her renderda aynı - yeni DOM. React her seferinde DOM'u güncelleyecektir.
Alex Shwarc

4

.bindDahil olmayan bir başka seçenek veya ES6, ana işleyiciyi gerekli sahne ile çağırmak için bir işleyici ile bir alt bileşen kullanmaktır. İşte bir örnek (ve çalışan örneğe bir bağlantı aşağıdadır):

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);
    }
  }
});

Temel fikir, üst bileşenin onClickişlevi bir alt bileşene geçirmesidir . Alt bileşen onClickişlevi çağırır ve propskendisine (ve event) iletilen herhangi bir öğeye erişebilir , böylece eventüst öğenin onClickişlevi içinde herhangi bir değer veya başka sahne kullanmanıza izin verir .

İşte bu yöntemi çalışırken gösteren bir CodePen demosu .


4

E.preventDefault () çağrıları dahil OP'nin sorusunu yanıtlamak için alternatif bir girişimde bulunmak:

Oluşturulan bağlantı ( ES6 )

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

Bileşen İşlevi

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

4

Bunun partiye oldukça geç olduğunu fark ettim, ancak çok daha basit bir çözümün birçok kullanım durumunu tatmin edebileceğini düşünüyorum:

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

    ...

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

Bir data-özellik de kullanabileceğinizi düşünüyorum .

Basit, anlamsal.


4

Bunun gibi bir işlev oluşturmanız yeterlidir

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

ve ihtiyacın olan yerde ara

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


3

Kullanıyorsanız bunu yapabilirsiniz 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

Uygulama, bir nesneden toplam sayımı aşağıda açıklandığı gibi anadan alt bileşenlere parametre olarak geçirerek gösterir.

İşte 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;

Ve İşte 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>
    )
  }
};

Yukarıda uygulamayı deneyin ve pass parametrelerinin herhangi bir DOM yönteminde reaktjs'de nasıl çalıştığına dair kesin senaryo elde edersiniz.


3

Burada kabul edilen cevapları temel alan bu amaçla yeniden kullanılabilecek bir sarıcı bileşen yazdım. Ancak yapmanız gereken tek şey bir dize geçirmekse, bir data niteliği ekleyin ve e.target.dataset'ten okuyun (bazılarının önerdiği gibi). Varsayılan olarak, paketleyicim bir işlev olan ve 'on' ile başlayan herhangi bir pervaneye bağlanacak ve diğer tüm olay argümanlarından sonra veri pervanesini otomatik olarak arayana geri gönderecektir. Performans için test etmeme rağmen, sınıfı kendiniz oluşturmaktan kaçınma fırsatı verecektir ve şöyle kullanılabilir:

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

veya Bileşenler ve fonksiyonlar için

const DataInput = withData(SomeComponent);

ya da isterseniz

const DataButton = withData(<button/>)

konteynerin dışında (ithalatınızın yanında)

İşte bir kapta kullanım:

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>
        );
    }
}

İşte 'withData.js sarmalayıcı kodu:

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 Events bu konuda 3 öneriniz var -

  1. Aslında, kodumuzda .bind () veya Arrow işlevini kullanmamız gerekmez. Kodunuzda basit bir şekilde kullanabilirsiniz.

  2. Performansı artırmak için onClick olayını th (veya ul) 'den tr (veya li)' ye taşıyabilirsiniz. Temel olarak n li öğeniz için n sayıda "Olay Dinleyicisi" olacaktır.

    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>

    // Ve erişebileceğiniz item.idde onItemClickaşağıda gösterildiği gibi yöntemle:

    onItemClick = (event) => {
       console.log(e.target.getAttribute("item.id"));
    }
  3. ListItem ve List için ayrı React Bileşeni oluşturmak için yukarıda belirtilen yaklaşıma katılıyorum. Bu marka kodu iyi görünüyor ancak 1000 li varsa 1000 Olay Dinleyici oluşturulur. Lütfen olay dinleyicinizin fazla olmadığından emin olun.

    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
Aktarmanız gereken veriler bir nesne olduğunda bu çalışmaz. Özellik yalnızca dizelerle çalışır. Ayrıca get niteliği ile dom okumak muhtemelen daha pahalı bir işlemdir.
SlimSim

2

Ben iki şekilde yöntemine onclick olay değeri geçmek için kod ekledim. 1. bind yöntemini kullanarak 2. arrow (=>) yöntemini kullanarak. handlesort1 ve handlesort yöntemlerine bakın

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

Aşağıda, onClick olayında değer ileten örnek verilmiştir.

Es6 sözdizimini kullandım. sınıfta hatırla bileşen ok işlevi otomatik olarak bağlanmaz, bu nedenle yapıcıda açıkça bağlanır.

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

Metodu React'in sınıf örneğine bağlamanız gerekecek. React'taki tüm yöntemleri bağlamak için bir kurucu kullanmak daha güvenlidir. Parametreyi yönteme geçirdiğinizde, ilk parametre yöntemin 'bu' bağlamını bağlamak için kullanılır, böylece yöntemin içindeki değere erişemezsiniz.


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

Çok kolay bir yolu var.

 onClick={this.toggleStart('xyz')} . 
  toggleStart= (data) => (e) =>{
     console.log('value is'+data);  
 }

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
Bu kod soruyu çözebilir, ancak bir açıklama da dahil olmak üzere , yayınınızın kalitesini artırmaya yardımcı olur. Gelecekte okuyucular için soruyu cevapladığınızı ve bu kişilerin kod önerinizin nedenlerini bilmeyebileceğini unutmayın.
Shree

2

Bu sorunun hiçbir yerine .bindgelmiyor , ama bence hile yapacak. Aşağıdaki örnek kodu bulun.

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

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

1

Ok fonksiyonu kullanarak:

Aşama-2'yi kurmalısınız:

npm babel-preset-stage-2 kurulumu:

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

Bunu ele almanın 3 yolu vardır: -

  1. Yapıcıda yöntemi aşağıdaki gibi bağlayın: -

    export class HeaderRows extends Component {
       constructor() {
           super();
           this.handleSort = this.handleSort.bind(this);
       }
    }
  2. Şu şekilde oluştururken ok işlevini kullanın: -

    handleSort = () => {
        // some text here
    }
  3. Üçüncü yol şudur: -

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

0

Kodunuzu şu şekilde kullanabilirsiniz:

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

Burada e olay nesnesi içindir, eğer preventDefault()tanıtıcı fonksiyonunuzda olduğu gibi olay metotlarını kullanmak veya gibi hedef değer veya isim almak istiyorsanız e.target.name.


0

Param'ı bir etiketin niteliği olarak geçirmenin çözümünü oldukça makul buldum.

Ancak sınırlamaları vardır:

  • Liste öğesinde başka etiketler olduğunda düzgün çalışmaz (dolayısıyla event.target amaçlanandan farklı olabilir)
  • Param yalnızca bir dize olabilir. Serileştirme ve serileştirme gerektirir.

Bu yüzden bu kütüphaneyi buldum: tepki-olay-param

O:

  • Gerektiğinde ebeveynlerde gerekli özniteliği arayarak çocukların sorununu çözer
  • Paramı otomatik olarak serileştirir ve serisini kaldırır
  • Ayarlama ve alma mantığını içine alır. Param isimleriyle uğraşmanıza gerek yok

Kullanım örneği:

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

Hepsi boşlukta birçok performans düşüncesi vardı.
Bu işleyicilerle ilgili sorun, sahne malzemelerine adlandıramayacağınız argümanı dahil etmek için onları körelemeniz gerektiğidir.
Bu, bileşenin tıklanabilir her öğe için bir işleyiciye ihtiyacı olduğu anlamına gelir. Birkaç düğme için bunun bir sorun olmadığını kabul edelim, değil mi?
Sorun, düzinelerce sütun ve binlerce satır içeren sekmeli verileri işlerken ortaya çıkar. Orada o kadar çok işleyici yaratmanın etkisini fark ediyorsunuz.

Gerçek şu ki, sadece birine ihtiyacım var.
İşleyiciyi tablo düzeyinde (veya UL veya OL ...) ayarladım ve tıklama gerçekleştiğinde, olay nesnesindeki her zaman mevcut olan verileri kullanarak tıklanan hücrenin hangisi olduğunu söyleyebilirim:

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

Tagname alanlarını, tıklamanın geçerli bir öğede olup olmadığını denetlemek için kullanıyorum, örneğin THs ot altbilgilerindeki tıklamaları yoksay.
RowIndex ve cellIndex, tıklanan hücrenin tam konumunu verir.
Metin içeriği, tıklanan hücrenin metnidir.

Bu şekilde hücrenin verilerini işleyiciye geçirmem gerekmez, kendi kendine hizmet verebilir.
Daha fazla veri, görüntülenmeyecek veriler gerekiyorsa, veri kümesi özniteliğini veya gizli öğeleri kullanabilirim.
Bazı basit DOM navigasyonuyla her şey elinizin altında.
PC'lerin bataklık yapması çok daha kolay olduğu için bu HTML'de her zamandan beri kullanılıyor.


0

Olay işleyicilerinde parametre geçirmenin birkaç yolu vardır, bazıları aşağıdadır.

Bir olay işleyiciyi sarmak ve parametreleri iletmek için bir ok işlevi kullanabilirsiniz:

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

yukarıdaki örnek çağrıya eşdeğerdir .bindveya açıkça bağlama'yı arayabilirsiniz.

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

Bu iki yaklaşımın dışında, köri işlevi olarak tanımlanan bir işleve argümanlar da iletebilirsiniz.

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

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

-1

Bir kapak kullanın , temiz bir çözümle sonuçlanır:

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

handleSort işlevi, değer sütunu önceden ayarlanmış bir işlevi döndürür .

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

Anonim işlev, kullanıcı th'yi tıklattığında doğru değerle çağrılır.

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


-2

Basit değiştirme gereklidir:

kullanım <th value={column} onClick={that.handleSort} >{column}</th>

onun yerine <th value={column} onClick={that.handleSort} >{column}</th>

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.