我有这些父子组件,我想通过点击功能来选择子组件中的项目.然而,似乎子组件中的函数被自动调用而不是等到用户单击元素.为了使它更清楚,我的父母和孩子组件
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调用它,您可以选择:
>使用handleClick.bind(this,item)将其与item绑定. bind创建一个新函数将具有预定义的第一个参数 – item
>传递新的箭头函数,如()=> handleClick(项目)
以下示例:
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所写,这种方法有一个缺点.由于新创建的箭头函数和.bind每次调用ChildItem的render方法时都会创建新函数,因此,与之前的“缓存”渲染方法结果相比,react会威胁生成的react元素,这意味着可能它可能在未来导致一些性能问题,甚至有关于eslint这个问题的规则,但你不应该仅仅因为两点而遵循这个规则.
1)应测量性能问题.我们不禁止使用Array.prototype.forEach支持常规for,因为for是相同或“更快”.
2)将click处理程序定义为类属性会导致增加组件实例的初始化步骤.重新渲染是快速有效的反应,因此有时初始渲染更重要.
只是使用对你更好的东西,并可能阅读像这样的文章https://cdb.reacttraining.com/react-inline-functions-and-performance-bdff784f5578