我将举例说明我的问题......
说我有以下数据:
const widgets = [
{ id: 1, name: 'Foo' },
{ id: 2, name: 'Bob' }
];
它作为prop传递给组件,然后映射到元素中,如下所示:
class WidgetSelector extends Component {
onSelected = (widget) => {
console.log('Selected widget: ', widget);
}
render() {
return (
<div>
{
this.props.widgets.map((widget, i) =>
<button key={i} onClick={() => this.onSelected(widget)}>
{widget.name}
</button>
)
}
</div>
);
}
}
它在表面区域似乎没问题,但它正在打破performance optimisation guidelines,因为每个render()
都会创建一个新的函数实例(参见onClick={() => onSelected(widget)}
)。因此,这会破坏子组件的“纯粹”更新特性,并且每次父渲染调用都会强制进行子渲染,即使可能没有对子组件进行任何实际更改。
我链接的文章引用了构造函数中的早期绑定机制,但我的情况不同,我需要根据props传递参数。
避免此类情况的推荐模式是什么?
我应该在组件的构造函数中创建一个函数数组,然后通过索引引用函数吗?像这样:
class WidgetSelector extends Component {
constructor(props) {
super(props);
this.widgetSelectors = props.widgets.map(
widget => () => this.onSelected(widget)
);
}
...
render() {
return (
<div>
{
this.props.widgets.map((widget, i) =>
<button key={i} onClick={this.widgetSelectors[i]}>
{widget.name}
</button>
)
}
</div>
);
}
}
这有效,但这是解决这个问题最优雅的方法吗?
如果你想玩,我已经创建了这个解决方案的webpackbin实现:http://www.webpackbin.com/4ybibSU7b
答案 0 :(得分:1)
您引用的文章通过早期绑定指出了解决方法
class WidgetSelector extends Component {
constructor(props) {
super(props);
this.onSelected = this.onSelected.bind(this);
}
onSelected(e) {
console.log(e.target.innerHTML);
}
render() {
return (
<div>
{
this.props.widgets.map((widget, i) =>
<button key={i} onClick={this.onSelected}>
{widget.name}
</button>
)
}
</div>
);
}
}
但是这样你就无法直接将参数传递给函数。
答案 1 :(得分:1)
您可以将数据作为属性添加到元素上,并以这种方式引用它:
var Container = React.createClass({
data: ['foo', 'bar'],
handleClick: function(e) {
console.log(e.target.getAttribute('data-item'))
},
render: function() {
return <div>
{this.data.map(d =>
<button key={d} data-item={d} onClick={this.handleClick}>{d}</button>)}
</div>;
}
});
答案 2 :(得分:0)
尝试;
<button key={i} onClick={onSelected.bind(this, widget)}>