#React中类组件中关于回调函数的一个问题
在ES6中,类中定义的方法,是放在原型对象的,供实例对象引用。
//创建一个Person类
class Person {
constructor(name,age) {
this.name = name;
this.age = age;
}
}
class Student extends Person {
constructor(name,age,grade) {
super(name,age);
this.grade = grade;
}
study() {
console.log(this);
}
}
const st = new Student("john", 12, 'sdfjk');
st.study();
const x = st.study;
x();
所以,在st
调用study
方法时候,输出的是该实例对象,而将st.study方法赋值给x时,再调用x,那么类中定义的方法都是局部严格模式,所以该方法中的this就是undefined。
而将代码改为:
const st = new Student("john", 12, 'sdfjk');
st.study();
const x = st.study.bind({name:'Tom',age:18});
x();
此时,x中的this就是对象{name:"Tom",age:18}了,输出如下:
下面上jsx代码:
class Weather extends React.Component{
constructor(props){
super(props);
this.state={isHot:false};
}
render(){
return <h1 onClick={this.changeWheather}>今天天气很炎热</h1>
}
changeWheather(){
console.log(this);
}
}
ReactDOM.render(<Weather/>,document.getElementById("test"));
点击,发现changeWheather
打印的是undefined。
是因为changeWheather是作为onCick的回调,而部是通过实例调用的,是直接调用类中的方法,默认开启了局部的严格模式,当点击时,调用changeWheather方法,而该方法并不是实例调用的,开启严格模式,所以this就是undefined,所以打印的是undefined。
而改正的方法,就是通过bind,将类中定义的changeWheather方法中的this改为实例对象。
class Weather extends React.Component{
constructor(props){
super(props);
this.state={isHot:false};
this.test=this.nice.bind(this);
}
render(){
return <h1 onClick={this.test}>今天天气很炎热</h1>
}
nice(){
console.log(this);
}
}
ReactDOM.render(<Weather/>,document.getElementById("test"));
上述修改,当点击时,触发test方法,虽然同样也不是实例对象调用的,但test方法中的this就是实例对象,因为在constructor构造器中,已经通过bind,将nice方法中的this变成了实例对象,所以,输出的是实例对象
上述修改只是为了,更明显的说明,实际上可以:
class Weather extends React.Component{
constructor(props){
super(props);
this.state={isHot:false};
this.changeWheather=this.changeWheather.bind(this);
}
render(){
return <h1 onClick={this.changeWheather}>今天天气很炎热</h1>
}
changeWheather(){
console.log(this);
}
}
ReactDOM.render(<Weather/>,document.getElementById("test"));
可以看到,实例中也有一个changeWheather
方法,这里,在赋值给回调函数时候,首先发现了实例的changeWheateher
,所以就不会调用原型对象上的changeWheather
方法。
精简写法
class Weather extends React.Component{
//可以去掉构造器
//直接用赋值语句,给实例增加属性。
state={isHot:false};
render(){
const isHot=this.state.isHot;
return <h1 onClick={this.changeWheather}>今天天气很{isHot?"炎热":"凉爽"}</h1>
}
//自定义方法,要用赋值语句的形式+箭头函数,箭头函数中的this,就会往外寻找this,而由于是赋值语句
//所以该属性是放在实例上的,而又因为是箭头函数,所以this,外寻,找到了实例,所以,此处里面的this就是实例。
changeWheather=()=>{
const isHot=this.state.isHot;
this.setState({isHot:!isHot});
}
}
ReactDOM.render(<Weather/>,document.getElementById("test"));
关于类中赋值语句+箭头函数的this指向的测试如下:
#####
愿你一寸一寸地攻城略地,一点一点地焕然一新
#####