React:如何将参数传递给回调

时间:2017-01-23 13:31:51

标签: javascript performance reactjs

我的反应组件中有一个元素列表,我希望它们是可点击的。点击后,我调用一些外部函数在参数中传递项目ID:

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

此代码有效,但它有很大的性能缺点:每次调用render时都会创建许多新的匿名函数。

如何在此处将doSomething函数作为参考传递,同时仍能为其提供item.id

3 个答案:

答案 0 :(得分:6)

您可以使用数据属性,在使用相同功能时为每个项目设置正确的ID:

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

在元素中设置data-*属性时,您可以使用散列形式的dataset将其恢复。例如,在doSomethingFromEvent我有event.target.dataset = {id: *id*}See more on MDN

使用<li key={item.id} data-myattriute={myvalue} onClick={this.handleClick}></li>更新哈希(例如状态)时更加清晰,我可以简单地定义handleClick,例如:

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

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

回到你的问题,这种方法的好处是,如果你确保你的容器元素(ul)不能在数据属性(li)的子项外部点击,这是你的情况,你可以声明函数在它上面:

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

现在您的功能只创建一次,甚至不会在每个项目中重复。

答案 1 :(得分:1)

您可以为数组中的每个项目创建一个新组件,并使用道具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>;
  }
}

答案 2 :(得分:0)

你可以做的是创建一个部分应用或更高阶的函数来封闭item.id并传递它。因此,让我们看一下这个玩具的例子:

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

}

现在,您可以访问1234以及event对象

这是使用transform-class-properties babel插件。如果不使用或不能使用它,你可以做这样的事情:

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

但是你必须在通话过程中绑定this而我到处都不喜欢它。