ReactNative:踩过的那些坑
2017-10-20 本文已影响0人
程序猿司令
1.this.setState is not a function
//错误代码示例
export default class App extends Component<{}> {
constructor (props){
super(props);
this.state = {
clicked:false,
selectedTab:'main'
}
}
clickme(){
this.setState({
clicked:true
})
}
render(){
<View style={styles.container}>
<Text style={styles.welcome} onPress={this.clickme}>
Welcome to React Native!
</Text>
</View>
}
}
问题分析
this.setState is not a function 是说setState不是一个方法。但是我们明明就已经定了该方法,为什么还会出现如此问题?只有一种可能,就是当前引用的this和this.setState的this不是指向同一个对象,这样才会出现“this.setState is not a function”这样的错误我们可以在clickme()方法中添加一行代码,输出当前this对象:
clickme(){
console.log(this);
this.setState({
clicked:true
})
}
我们发现代码中this.setState的this指向的是当前函数对象,因此引用就报错,Google了一下解释是
this所指的就是包含this指针的上层对象,也就是当前实例的对象
这就是ES6和ES5的区别,ES6在定义方法的时候需要绑定当前this对象而ES5会“autobinding”自动指定当前对象
解决问题方法(推荐第三种方法主要是简洁,不过没个人看法不一样,按照自己习惯来就好)
//方法一
export default class App extends Component<{}> {
constructor (props){
super(props);
//绑定this
this.clickme = this.clickme.bind(this);
this.state = {
clicked:false,
selectedTab:'main'
}
}
clickme(){
this.setState({
clicked:true
})
}
render(){
<View style={styles.container}>
<Text style={styles.welcome} onPress={this.clickme}>
Welcome to React Native!
</Text>
</View>
}
}
//方法二
export default class App extends Component<{}> {
constructor (props){
super(props);
this.state = {
clicked:false,
selectedTab:'main'
}
}
clickme(){
this.setState({
clicked:true
})
}
render(){
<View style={styles.container}>
//绑定this
<Text style={styles.welcome} onPress={this.clickme.bind(this)}>
Welcome to React Native!
</Text>
</View>
}
}
//方法3
export default class App extends Component<{}> {
constructor (props){
super(props);
this.state = {
clicked:false,
selectedTab:'main'
}
}
//采用ES6 箭头函数的写法,既方便又整洁
clickme = ()=> {
this.setState({
clicked:true
})
}
render(){
<View style={styles.container}>
<Text style={styles.welcome} onPress={this.clickme}>
Welcome to React Native!
</Text>
</View>
}
}