我有这些父级和子级组件,我想通过点击功能在子级组件中选择一个项目。但是,似乎子组件中的函数会自动调用,而不是等到用户单击该元素。为了更清楚一点,这里是我的父级和子级组件

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,而不是传递的函数调用的结果。

如果要使用param调用它,则可以选择:


item将其与handleClick.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所写,这种方法有一个缺点。由于每次调用.bindrender方法时,新创建的箭头函数和ChildItem也会创建新函数,因此与以前的render缓存结果相比,react威胁到所得的react元素将有所不同>方法,这意味着将来可能会导致一些性能问题,对于eslint甚至有关于此问题的规则,但是由于两点,您不应该仅遵循此规则。

1)应测量performance problems。我们不禁止使用Array.prototype.forEach代替常规的for,因为for相同或“更快”。

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

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

09-25 17:37
查看更多