使用子组件中的箭头函数反应传递参数

Dio*_*rza 8 ecmascript-6 reactjs ecmascript-7

我有这些父子组件,我想通过点击功能来选择子组件中的项目.然而,似乎子组件中的函数被自动调用而不是等到用户单击元素.为了使它更清楚,我的父母和孩子组件

export class ParentView extends Component {
  state = {
    selectedItem: {}
  }

  handleClick = (item) => {
    alert('you click me');
    this.setState({selectedItem: item});
  } 

  render() {
    let item = { name: 'Item-1' };
    return (
      <div>
        <ChildItem item={item} handleClick={this.handleClick} />
      </div>
    );
  }
}

export class ChildItem extends Component {
  render() {
    const {item, handleClick} = this.props;
    return (
      <div>
        <a  onClick={handleClick(item)} />
      </div>
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

这些是使用箭头函数传递handleClick给子组件的我的组件,但是警报始终在第一次渲染时被调用,而不是由用户触发.有什么建议吗?

ula*_*mir 12

您应该将函数本身传递给onClick,而不是传递的函数调用的结果.

如果您想使用param调用它,您可以选择:

  • 用其绑定itemhandleClick.bind(this, item).bind创建一个新函数将有一个预定义的第一个参数 - item
  • 传递新的箭头功能 () => handleClick(item)

以下示例:

export class ChildItem extends Component {
  render() {
    const { item, handleClick } = this.props;

    return (
      <div>
        <a onClick={() => handleClick(item)} />
      </div>
    )
  }
}
Run Code Online (Sandbox Code Playgroud)

在你的代码中,你在onClick声明中调用一个函数,所以handleClick执行的结果将传递给你onClick,你很可能不会想要实现的.

<a onClick={handleClick(item)} />

更新:

正如@dhilt所写,这种方法有一个缺点.由于新创建的箭头函数并且.bind每次调用render方法时都会创建新函数ChildItem,因此反应将威胁生成的反应元素作为不同的render方法,与之前的"缓存" 方法结果相比,这意味着它可能会导致某些在将来的性能问题上,甚至有关于这个问题的规则,但是你不应该因为两点而遵循这个规则.

1)performance problems应该测量.我们不禁止使用Array.prototype.forEach支持常规for因为for相同或"更快".

2)将click处理程序定义为类属性会导致增加组件实例的初始化步骤.重新渲染是快速有效的反应,因此有时初始渲染更重要.

只是使用对你更好的东西,并可能阅读这样的文章https://cdb.reacttraining.com/react-inline-functions-and-performance-bdff784f5578

  • 谢谢,我用`onClick = {()=> handleClick(item)}`来解决它 (4认同)

dhi*_*ilt 6

接受的答案会影响性能:ChildItem即使数据没有改变,组件也会重新渲染,因为每个渲染分配一个新函数(这是因为.bind; 与箭头函数相同)。在这种特殊情况下,通过props从新的公共类字段中获取处理程序及其参数很容易避免这样的问题:

export class ChildItem extends Component {

  onClick = () => {
    this.props.handleClick(this.props.item);
  }

  render() {
    return (
      <div>
        <a  onClick={this.onClick} />
      </div>
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

ParentView 保持不变。