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

352
Views
Reaccionar: cómo pasar argumentos a la devolución de llamada

Tengo una lista de elementos dentro de mi componente de reacción y quiero que se pueda hacer clic en ellos. Al hacer clic, llamo a alguna función externa que pasa el ID del elemento en los argumentos:

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

Este código funciona, pero tiene un gran inconveniente de rendimiento: se crean muchas funciones anónimas nuevas en cada llamada para render .

¿Cómo puedo pasar esa función doSomething como una referencia aquí y al mismo tiempo poder proporcionarle un item.id ?

over 4 years ago · Santiago Trujillo
3 answers
Answer question

0

Puede usar atributos de datos para establecer la identificación correcta en cada elemento mientras usa la misma función:

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

Al configurar los atributos data-* en su elemento, puede recuperarlos con dataset , en forma de hash. Por ejemplo, en doSomethingFromEvent tengo event.target.dataset = {id: *id*} . Ver más en MDN

Esto es aún más limpio cuando se actualiza un hash (el estado, por ejemplo), con <li key={item.id} data-myattriute={myvalue} onClick={this.handleClick}></li> , simplemente puedo definir handleClick como:

 handleClick(event){ // Here event.target.dataset = {myattribute: myvalue} Object.assign(myObject, event.target.dataset); // or this.setState(event.target.dataset); }

Volviendo a su problema, lo mejor de este enfoque es que si se asegura de que no se pueda hacer clic en su elemento contenedor (ul) fuera de sus elementos secundarios con atributos de datos (li), que es su caso, puede declarar la función en él:

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

Ahora su función se crea una sola vez y ni siquiera se repite en cada elemento.

over 4 years ago · Santiago Trujillo Report

0

Lo que puede hacer es crear una función de orden superior o parcialmente aplicada para encerrar el item.id y pasarlo. Así que veamos un ejemplo de juguete de esto:

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

Ahora tiene acceso a 1234 junto con su objeto de event

Este es el uso del complemento babel transform-class-properties . Si no lo usa o no puede usarlo, probablemente pueda hacer algo como esto:

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

pero luego tendrá que vincular this durante su llamada y simplemente no me gusta eso en todas partes.

over 4 years ago · Santiago Trujillo Report

0

Puede crear un nuevo componente para cada elemento de la matriz y usar los accesorios, como este :

 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!