我有一个简单的react/redux应用程序,带有用于搜索表单的容器,带有两个目标自动选择组件:
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} />
)
}
}
这只是在某些事件上调用通过 props 传入的函数。
有自动绑定(bind)功能,但在 ES6 类中不可用:https://medium.com/@goatslacker/react-0-13-x-and-autobinding-b4906189425d#.nkv1cn32v 我看到很多解决方法,比如 http://www.ian-thomas.net/autobinding-react-and-es6-classes/ 或第三方库。
在将方法从容器传递到简单组件时,避免这种绑定(bind)(this)的现代方法是什么?
最佳答案
有很多现代方法,但它们都围绕相同的想法:)
您可以使用箭头函数:
<Destination
onSelectSuggest={destination => (
this.props.setDestination(destination, 'origin')
)}
/>
(我喜欢这个,因为我们可以放弃参数翻转 onSelectSuggest
方法!)
对于更简单的绑定(bind),您可以使用 ESNext 绑定(bind)运算符 (::
):
<Destination
enterText={::this.enterText}
/>
(显然,这需要 babel)
<小时/>编辑 2017 年 9 月 27 日:“bind”运算符似乎并未纳入规范;更现代的方法是使用属性初始化语法(也是即将推出的 JS 功能,但我相信它更有可能进入该语言):
class SomeComponent extends Component {
enterText = () => {
// body here
}
render() {
return <Destination enterText={this.enterText} />
}
}
<小时/>
最后,最有效的方法是在构造函数中进行绑定(bind)。
class QuoteBox extends Component {
constructor(props) {
super(props);
this.enterText = this.props.enterText.bind(this);
}
render() {
return (
<Destination
enterText={this.enterText}
/>
)
}
}
这样做更有效的原因是因为绑定(bind)非常慢,并且在您的示例中它是在每次渲染时完成的。最好在初始化时执行一次。
也就是说,无论哪种方式都可能并不重要。不要太担心性能,直到它成为一个问题; React 速度很快,除非您正在处理非常复杂的组件树,否则差异可能可以忽略不计。
同样,在 AutoComplete 中,您应该在构造函数中绑定(bind) 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}
/>
)
}
}
关于reactjs - 如何避免在react/redux容器中与组件(ES6类)绑定(bind),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38168886/