JavaScript中this的绑定是头疼的问题,于是出现了call,apply,bind三兄弟用来改变函数调用时this的指向
react环境下也存在这个问题, 第一次碰到这个问题时,不免会认为啥react连这个都没搞定
class Search extends Component {
static propTypes = {
onSearch: React.PropTypes.func.isRequired
}
onSearch() {
console.log('表单值:', this.field.getValues());
this.props.onSearch(this.field.getValues());
}
render(){
const {init} = this.field;
return <div>
<Form direction="hoz" labelAlign="left">
<FormItem label="loginID:">
<Input placeholder="请输入loginID" {...init('loginID')}/>
</FormItem>
{/*这里的this其实指向window 而不是我们想当然的Search,函数的this指向跟函数的执行上下文时有关系的*/}
<Button type="primary" onClick={this.onSearch}>搜索</Button>
</Form>
</div>
}
}
解决办法
1、 通过bind绑定
class Search extends Component {
render(){
return <div>
<Form direction="hoz" labelAlign="left">
<FormItem label="loginID:">
<Input placeholder="请输入loginID" {...init('loginID')}/>
</FormItem>
<Button type="primary" onClick={this.onSearch.bind(this)}>搜索</Button>
</Form>
</div>
}
}
2、 :: es7 stage-0 proposal, 其实就是bind的语法糖,babel已经支持
class Search extends Component {
render(){
return <div>
<Form direction="hoz" labelAlign="left">
<FormItem label="loginID:">
<Input placeholder="请输入loginID" {...init('loginID')}/>
</FormItem>
<Button type="primary" onClick={::this.onSearch}>搜索</Button>
</Form>
</div>
}
}
3、 在构造函数中统一绑定this
class Search extends Component {
constructor(props) {
super(props);
this.onSearch = this.onSearch.bind(this)
// 如果很多的 话,这里貌似有点臃肿
}
render(){
return <div>
<Form direction="hoz" labelAlign="left">
<FormItem label="loginID:">
<Input placeholder="请输入loginID" {...init('loginID')}/>
</FormItem>
<Button type="primary" onClick={this.onSearch}>搜索</Button>
</Form>
</div>
}
}
4、使用箭头函数 原理:箭头函数自身没有this的绑定,会寻找外层对象
class Search extends Component {
render(){
return <div>
<Form direction="hoz" labelAlign="left">
<FormItem label="loginID:">
<Input placeholder="请输入loginID" {...init('loginID')}/>
</FormItem>
<Button type="primary" onClick={(...args)=>{
this.onSearch( ...args)
}}>搜索</Button>
</Form>
</div>
}
}
5、 通过第三方插件 core-decorators.js
写法类似java的注解
class Search extends Component {
@autobind
onSearch() {
console.log('表单值:', this.field.getValues());
this.props.onSearch(this.field.getValues());
}
render(){
const {init} = this.field;
return <div>
<Form direction="hoz" labelAlign="left">
<FormItem label="loginID:">
<Input placeholder="请输入loginID" {...init('loginID')}/>
</FormItem>
<Button type="primary" onClick={this.onSearch}>搜索</Button>
</Form>
</div>
}
}
网友评论