user3348410
user3348410

Reputation: 2833

How pass to react list item to function as parameter at onClick

i wonder how i can pass as parameter to onClick function react list element

here is my list.

const items = this.state.tableData.items.map(
      (item, index) => <td key={index} onClick={this.getItem}>{item.name}</td>
    );

here is i define my function

constructor(props) {
    super(props);
    this.state = {
      tableData: this.props.items
    };
    this.getItem = this.getItem.bind(this);

  }

here is my function.

 getItem(item) {
    console.log(item)
  }

I wan't to get item details onClick to item where i render my list.

i tried to make onClick={this.getItem(item)} i get with this way item details but not at onClick. Just all items details console logged when i open my page.

what can i do ?

Upvotes: 3

Views: 5489

Answers (3)

parmigiana
parmigiana

Reputation: 301

Functional Components are going to win over classes. So better to be used with this:

      onClick={  ( item.id) => handleclick( item.id, [...])

Edit 1 Handleclick here intended as a Hook ( e. G. SetValue on useState).

Nb: On purpose code dirty to fight against the awful copypasta SO practice. Thanks redditors. Read the code, then read the memes.

Upvotes: 1

devserkan
devserkan

Reputation: 17598

This is just an alternative answer. Separating the item into its own component would be an alternative. In this way, you can pass the onClick function without binding it then use it in the Item component like this.

const items = [{ id: 1, name: "foo" }, { id: 2, name: "bar" }];

const Item = ({ item, getItem}) => {
  const handleClick = () => getItem(item);
  return (
    <div onClick={handleClick}>{item.name}</div>
  )
}

const App = () => {
  const getItem = item => console.log(item.id);
  return (
    <div className="App">
      {items.map(item => (
        <Item key={item.id} item={item} getItem={getItem} />
      ))}
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root" />

If there are so many items you can avoid rerendering all the items if none of their props changed since you don't use bind or any inline arrow function. But, as you can see it needs a separate component and some more coding.

Upvotes: 1

T.J. Crowder
T.J. Crowder

Reputation: 1074038

There are two common ways: Using an arrow function, or using bind:

Arrow function:

const items = this.state.tableData.items.map(
  (item, index) => <td key={index} onClick={e => this.getItem(item, e)}>{item.name}</td>
);

bind:

const items = this.state.tableData.items.map(
  (item, index) => <td key={index} onClick={this.getItem.bind(this, item)}>{item.name}</td>
);

In both cases, with the above, getItem would get the item as its first argument, the event object as its second.

Upvotes: 6

Related Questions