Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

351
Views
React: how to pass arguments to the callback

I have a list of elements inside my react component, and I want them to be clickable. On click I call some external function passing item ID in arguments:

render () {
  return (
    <ul>
      {this.props.items.map(item => (
        <li key={item.id} onClick={() => {doSomething(item.id)}></li>
      ))}
    </ul>
  )
}

This code works, but it has a big performance drawback: a lot of new anonymous functions are being created on each call to render.

How can I pass that doSomething function as a reference here while still being able to provide a item.id to it?

over 4 years ago · Santiago Trujillo
3 answers
Answer question

0

You could use data-attributes, to set the correct id on each item while using the same function:

function doSomethingFromEvent(event){
  return doSomething(event.target.dataset.id);
}

render () {
  return (
    <ul>
      {this.props.items.map(item => (
        <li key={item.id} data-id={item.id} onClick={doSomethingFromEvent}></li>
      ))}
    </ul>
  )
}

When setting data-* attributes in your element, you can get it back with dataset, in the form of a hash. For example, in doSomethingFromEvent I have event.target.dataset = {id: *id*}. See more on MDN

This is even cleaner when updating a hash (the state for example), with <li key={item.id} data-myattriute={myvalue} onClick={this.handleClick}></li>, I can simply define handleClick such as:

handleClick(event){
    // Here event.target.dataset = {myattribute: myvalue}

    Object.assign(myObject, event.target.dataset);
    // or
    this.setState(event.target.dataset);
}

Coming back to your problem, the great thing with this approach is that if you ensure your container element (ul) cannot be clicked outside its children with data-attributes (li), which is your case, you can declare the function on it:

render () {
  return (
    <ul onClick={doSomethingFromEvent}>
      {this.props.items.map(item => (
        <li key={item.id} data-id={item.id}></li>
      ))}
    </ul>
  )
}

Now your function is created a single time, and is not even repeated in each item.

over 4 years ago · Santiago Trujillo Report

0

What you can do is create a partially applied or higher order function to enclose the item.id and pass it along. So let's look at a toy example of this:

class App {

   partiallyApplied = id => e => {
     console.log(id,'this is passed in first')
     console.log(e,'this is passed in second')
   }

   render(){
     return (
       <button onClick={this.partiallyApplied(1234)}>Click Me</button>
     )
   }

}

Now you have access to 1234 along with your event object

This is use transform-class-properties babel plugin. If do not or cannot use that, you can probably do something like this:

partiallyApplied(id){
  return function(e){
   console.log(id,'this is id')
   console.log(e,'this is event')
  }
}

but then you will have to bind this during your call and I just don't like that everywhere.

over 4 years ago · Santiago Trujillo Report

0

You could create a new component for every item in the array and use the props, like this:

class Li extends React.Component {
  render() {
    return <li onClick={this.onClick}> {this.props.children} </li>;
  }
  onClick = () => {
    console.log(this.props.item);
  };
}

class App extends React.Component {
  state = {
    items: [
      {id: 1, name: 'one'},
      {id: 2, name: 'two'},
      {id: 3, name: 'three'},
    ]
  };
  render() {
    return <ul> 
      {this.state.items.map(i => 
        <Li key={i.id} item={i}>{i.name}</Li>
      )} 
    </ul>;
  }
}
over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!