我有简单的react / redux app和带有两个目标自动选择组件的搜索表单的容器:
class QuoteBox extends Component {
onSelectSuggest(target, destination) {
this.props.setDestination(destination, target);
}
render() {
return (
<Destination
direction="From"
key="dest-from"
enterText={this.props.enterText.bind(this)}
onSelectSuggest={this.onSelectSuggest.bind(this, "origin")}
dataSource={this.props.originSuggests} />
<Destination
direction="To"
key="dest-to"
enterText={this.props.enterText.bind(this)}
onSelectSuggest={this.onSelectSuggest.bind(this, "destination")}
dataSource={this.props.destinationSuggests} />
)
}
}
function mapStateToProps(state) {
return {
originSuggests: state.originSuggests,
destinationSuggests: state.destinationSuggests,
origin: state.origin,
destination: state.destination
}
}
function mapDispatchToProps(dispatch) {
return bindActionCreators({
enterText: enterText,
setDestination: setDestination
}, dispatch)
}
export default connect(mapStateToProps, mapDispatchToProps )(QuoteBox)
和Destination是一个简单的组件,如
export default class Destination extends Component {
render() {
return (
<AutoComplete
onUpdateInput = { _.debounce((term) => {
this.props.enterText(term);
this.setState({
searchText: term
})
}, 300) }
onNewRequest = {(x) =>{this.props.onSelectSuggest(x)}}
dataSource={this.props.dataSource} />
)
}
}
在一些事件中只调用通过道具传递的函数。
有autobind功能但在ES6课程中不可用:https://medium.com/@goatslacker/react-0-13-x-and-autobinding-b4906189425d#.nkv1cn32v 我看到很多变通办法 http://www.ian-thomas.net/autobinding-react-and-es6-classes/ 或第三方图书馆。
在将容器中的方法传递给简单组件时,什么是避免这种绑定(this)的现代方法?
答案 0 :(得分:5)
有许多现代方法,但它们都围绕着相同的想法:)
您可以使用箭头功能:
<Destination
onSelectSuggest={destination => (
this.props.setDestination(destination, 'origin')
)}
/>
(我喜欢这个,因为我们放弃了论证 - 翻转onSelectSuggest
方法!)
对于更简单的绑定,您可以使用ESNext绑定运算符(::
):
<Destination
enterText={::this.enterText}
/>
(显然,那个人需要巴贝尔)
编辑2017年9月27日:&#39; bind&#39;运营商似乎没有将其纳入规范;更现代的方法是使用属性初始化器语法(也是即将推出的JS功能,但我相信它更有可能使其成为语言):
class SomeComponent extends Component {
enterText = () => {
// body here
}
render() {
return <Destination enterText={this.enterText} />
}
}
最后,最有效的方法是在构造函数中进行绑定。
class QuoteBox extends Component {
constructor(props) {
super(props);
this.enterText = this.props.enterText.bind(this);
}
render() {
return (
<Destination
enterText={this.enterText}
/>
)
}
}
这更有效的原因是因为绑定非常慢,并且在您的示例中,它是在每个渲染上完成的。当它被初始化时,最好这样做一次。
那就是说,它可能并不重要。在成为问题之前,不要过分担心性能; React很快,除非你处理一个非常复杂的组件树,否则它可能是一个微不足道的差异。
同样,在AutoComplete中,您应该在构造函数中绑定debounced函数:
class Destination extends Component {
constructor(props) {
super(props);
this.updateInput = _.debounce(this.updateInput, 300)
updateInput(term) {
this.props.enterText(term);
this.setState({
searchText: term
})
}
render() {
return (
<AutoComplete
onUpdateInput={this.updateInput}
onNewRequest={this.props.onSelectSuggest}
/>
)
}
}