var List = React.createClass({
render() {
let { handleClick } = this.props;
return (
<ul>
{this.props.items.map(item =>
<li key={item.id} onClick={handleClick.bind(this, item.id)}>
{item.name}
</li>
)}
</ul>
);
}
});
在这里解释一下,避免在render中使用bind,你可以使用这样一个小技巧。
var List = React.createClass({
render() {
let { handleClick } = this.props;
// handleClick still expects an id, but we don't need to worry
// about that here. Just pass the function itself and ListItem
// will call it with the id.
return (
<ul>
{this.props.items.map(item =>
<ListItem key={item.id} item={item} onItemClick={handleClick} />
)}
</ul>
);
}
});
var ListItem = React.createClass({
render() {
// Don't need a bind here, since it's just calling
// our own click handler
return (
<li onClick={this.handleClick}>
{this.props.item.name}
</li>
);
},
handleClick() {
// Our click handler knows the item's id, so it
// can just pass it along.
this.props.onItemClick(this.props.item.id);
}
});
原文链接:Don't Use Bind When Passing Props
如今我们在编写
React
组件时经常会遇到通过props
传递一个函数的情况,通常父组件向子组件传递一个回调函数,子组件事件触发这个回调函数可以改变父组件的状态。因而,维持这个回调函数的
this
指向便显得十分重要。以下有许多方法能保证
this
能准确挂载于组件上。毫无疑问,一些方法是较为优秀的,我们推荐使用这些方式来传递this
。自动绑定(good, 只能通过 React.createClass)
当你使用
React.createClass
创建你的组件时,你的组件上的所有方法都会被自动地绑定在你的组件作用域内。即便不使用bind
你也可以自由准确地在组件中传递你的回调。在render中使用bind(bad, ES6)
当我们使用
ES6
的class
语法时,React
不能够自动地将其成员函数绑定到组件上。像下面这个例子:在传递回调函数的最后时刻绑定
this
是一种能让你的应用正常工作的方式之一。但是,这样做会导致每次组件重新渲染(re-render
)时都会创建一个新的函数,因而会使得你的应用性能有明显的降低。其实,这个问题并不是说每次创建函数时都会产生较大的性能消耗。它指的是每时每刻通过
bind
创建的函数都会通过props
传递一个同样功能的新函数到你的子组件。当这种情况发生时,子组件上的shouldComponentUpdate
便会反复触发,因而产生大量的性能消耗,直至你的应用崩溃。以下这种绑定
this
的方式也会导致你在创建新函数的时候render
被反复触发。在render中使用箭头函数(bad, ES6)
与上面的例子类似,如果你期望使用箭头函数代替使用
bind
去绑定组件作用域,也同样会导致你在创建新函数的时候render
被反复触发。虽然这种方式看起来很棒,然而,并不推荐。在Class实例作用域中使用箭头函数(good, ES8+)
在组件创建时,我们通过声明一个实例方法
handleClick
。而在render
和其它函数组件方法中,使用this.handleClick
调用这个方法。此时我们并不用担心this
绑定的问题,因为箭头函数的语法糖,其已经自动绑定this
。因为从
ES标准
上来说,这种方式已经不属于ES6
或ES7
的范畴了。因而被贴上了ES8+
的标签。随着ES2016
标准(其中主要包含Array.prototype.includes
以及求幂操作符
)的最终定稿,即便未来这样的语法会加入标准,那也应该被称作ES2017(ES8)
及其后的版本了。虽然这种语法已经被
Babel
支持,但使用这样的尚未进入ES标准
的语法仍旧存在一定风险。即便如此,许多人仍然在使用这种语法,让它看起来已经被内定入ES标准
的样子。通过构造函数绑定this(good, ES6)
你可以使用构造函数绑定
this
,此后你便不用担心其指向的问题了。但注意:不要忘记super(props)
。使用修饰器语法(good, ES8+)
可以使用叫做autobind-decorator 的库。
@autobind
修饰器将handleClick
方法自动绑定上了this
。如果你嫌这样做都不过瘾,你甚至可以在Class
入口处使用它。然而,
ES2016/ES2017
依然没有把这种语法列入标准。即便这种语法已经被Babel
所支持,但现在使用这种语法仍旧存在一定风险。勿要使用bind传递参数
在回调函数调用的时候,给回调函数预设参数显得十分普遍,特别是在数组遍历中,看下面这个例子:
在这里解释一下,避免在
render
中使用bind
,你可以使用这样一个小技巧。