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

React passing parameter with arrow function in child component

我有这些父子组件,我想将点击功能传递给 select 子组件中的一个项目。然而,子组件中的函数似乎会自动调用,而不是等到用户单击该元素。为了更清楚这里是我的父组件和子组件

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

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

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

如果你想用参数调用它,你有以下选择:

  • 将其与 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>
    )
  }
}

在您的代码中,您在 onClick 声明中调用一个函数,因此 handleClick 执行的结果将传递给 onClick,这很可能不是您想要的实现。

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

更新:

正如@dhilt 所写,这种方法有一个缺点。由于每次调用 ChildItemrender 方法时,新创建的箭头函数和 .bind 也会创建新函数,与之前的 "cached" render 方法的结果,这意味着它可能会在未来导致一些性能问题,对于 eslint 甚至有关于这个问题的规则,但你不应该只遵循这条规则因为两点。

1) performance problems 应该测量。我们不禁止使用 Array.prototype.forEach 来支持常规 for,因为 for 与 "faster" 相同。

2) 将点击处理程序定义为 class 属性会导致组件实例的初始化步骤增加。重新渲染在反应中快速高效,所以有时初始渲染更重要。

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

ES6方式:

使用箭头函数=>

onClick={() => handleClick(item)}

(@havenchyk 的回答是 ES5 方式)。

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

export class ChildItem extends Component {

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

  render() {
    return (
      <div>
        <a  onClick={this.onClick} />
      </div>
    );
  }
}

ParentView 保持不变。