在子组件中用箭头函数反应传递参数
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
,而不是传递函数调用的结果。
如果你想用参数调用它,你有以下选择:
- 将其与
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 所写,这种方法有一个缺点。由于每次调用 ChildItem
的 render
方法时,新创建的箭头函数和 .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
保持不变。
我有这些父子组件,我想将点击功能传递给 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
,而不是传递函数调用的结果。
如果你想用参数调用它,你有以下选择:
- 将其与
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 所写,这种方法有一个缺点。由于每次调用 ChildItem
的 render
方法时,新创建的箭头函数和 .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
保持不变。