页面上是个用户注册的表单,刚刷新的时候不会报错,一旦开始输入就会报错,报错信息如图:
想必就是handleChange()
函数报错了
请问错在哪呢?
首先说一下你排除错误的方法,因为用react你会经常遇到Cannot read property 'xxxxx' of undefined这个错误,那么你想没想过console.log一下那个undefined的东西,并一路回溯回去找到他呢?
然后再来谈你这个问题的错误。这是一个js从娘胎里带来的毛病,我知道你肯定是这么写component的
class YourClass extends React.Component{
constructor(props){
super(props)
this.state={}
}
handleChange(e){
//.......
}
}
你在handleChange函数里面console.log(this)一下,会发现这个this是null,而不是你期待的YourClass,setState是YourClass从React.Component继承来的,null自然不会有setState这个方法。
那么就意味着你必须把外面的this指针传入handleChange函数里面。有大概三种方法
1、在调用的时候,看你这个情况应该是类似input或者textarea调用onChange方法时候调用的吧,原来你应该是这么写的:<input onChange={this.handleChange} />,把他改写成<input onChange={this.handleChange.bind(this)} />,这样,this指针就被传进去啦。
2、把handleChange函数用箭头函数的方式改写为
handleChange = (e) =>{
//.....内容不变
}
这样改写出来的函数会被自动bind上他所处的class的this指针。调用的时候原样调用即可。
3、类似方法1,好像看到还有一种<input onChange={::this.handleChange}/>的写法,作用一样,相当于语法糖,应该还需要babel配合一些plugin来支持,所以可以忽略这个方法,上面两种就够用了
说的很清楚了
this是undefined的
onChange的时候 this.handleChange.bind(this)一下就好了
@cheoyx 作用域的问题已经解决了,但有个新的问题,在表单内输入的时候,输入框里完全是空的,没有反应,也完全没报错,不知道怎么回事,应该怎么排查?以下是该组件的全部代码,如果有其他问题也欢迎提点,谢谢~~
import React, { Component } from 'react';
class Signup extends Component {
constructor(props){
super(props);
this.state = {
username: '',
nick: '',
password: ''
};
this.handleClick = this.handleClick.bind(this);
this.handleChange = this.handleChange.bind(this);
};
handleChange(e) {
this.setState({value: event.target.value});
};
handleClick() {
let data = {
username : this.state.username,
nick: this.state.nick,
password : this.state.password,
}
console.log(data);
};
render() {
let styles = {
signPagesStyle: {
display: 'flex',
flex: 1,
alignItems: 'center',
justifyContent: 'center',
flexShrink: 0
},
inputPosition: {
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'center'
},
inputMargin: {
margin: '20px 0'
},
buttonStyle: {
backgroundColor: '#03A9F4',
boxShadow: '0px 1px 6px rgba(0, 0, 0, 0.117647), 0px 1px 6px rgba(0, 0, 0, 0.117647)',
color: '#ffffff',
fontSize: '16px',
width: '160px',
height: '36px',
display: 'flex',
alignItems: 'center',
justifyContent: 'center'
}
}
return (
<div style={styles.signPagesStyle}>
<div style={styles.inputPosition}>
<div style={styles.inputMargin}>
<input type="text" onChange={this.handleChange} value={this.state.username} />
</div>
<div style={styles.inputMargin}>
<input type="text" onChange={this.handleChange} value={this.state.nick} />
</div>
<div style={styles.inputMargin}>
<input type="text" onChange={this.handleChange} value={this.state.password} />
</div>
<div style={styles.buttonStyle} onClick={this.handleClick}>注册</div>
</div>
</div>
)
}
}
export default Signup;
把你调用handleChange
的地方改改,我猜你现在是这么用的:
{ this.handleChange }
改成:
{ this.handleChange.bind(this) }
通常这个问题出现,是因为用了ES2015 class
,里面的no autobinding