关于React在近几天的学习中遇到了一个问题?(绑定事件this丢失)
首先我们现在了解一下类中传递this的指向方式
- 这个看起来似乎没什么问题?可以你接着往下看
class Test {
constructor() {
this.name = '2'
}
fun1() {
return this.fun2()
}
fun2() {
console.log(this)
console.log(this.name)
}
}
var test = new Test()
test.fun1()
--------输出------------
---Test { name: '2' }
---2
- 啊这个就有点奇怪了,this呢?
class Test {
constructor() {
this.name = '2'
}
fun1() {
var Fun = this.fun2
return Fun()
}
fun2() {
console.log(this)
console.log(this.name)
}
}
var test = new Test()
test.fun1()
--------输出------------
---undefined
---报错(this.name of undefined)
这是为什么呢?
正常情况下tihs都指向window而class里面只能指向class不能指向window当this向发生改变不指向class时指向就会丢失就成了未定义
所以是因为在返回函数值的时候我们把原来的this.fun2()
赋值给了一个变量,导致他的this不再指向本类了,就导致了this的消失。
回归正题
好了,例子也将完了,我们该回到正题了。
下面是React组件化开发的绑定事件,和上面讲的案例的情况很相似。具体是因为在return 时的jsx语法中他进行了赋值操作,导致了this的丢失所以在绑定的事件uLike
上才会导致this的丢失。
jsx的原理
jsx的原理本质上是React.createElement()
而React.createElement()有三个参数
第一个参数html标签的名字
第二个参数是传入的标签属性 传入的属性是以键值对的格式传入
第三个属性是节点要显示的内容
所以在第二个参数传入标签属性的时候 就相当于上面案例里的赋值 所以就这这时this就丢失了
class MyTest2 extends React.Component{
constructor(props) {
super(props);
this.state={
isLike:false
}
}
uLike(){
//获取state的值
var state=!this.state.isLike
//设置state的值取反
this.setState({
isLike:state
})
}
render(){
//读取状态
var {isLike}=this.state
//在这进行了赋值操作,所以让this就丢失了。所以调用类的构造函数时,this为undefined
return <h1 onClick={this.uLike}>{isLike?'你先还我':'我喜欢喜'}</h1>
}
}
//把组件的虚拟DOM映射到真实的DOM元素上
//复杂组件的渲染方式是1.根据渲染的组件先创建一个该类的对象,2.然后该对象调用render方法返回数据
ReactDOM.render(<MyTest2 />,document.getElementById('add'))
解决方法
1)把要绑定的事件声明为箭头函数,因为箭头函数没有真正的this执行,他取决与环境变量中的this,而环境变量中的this正好是类中的this
2)在constructor里使用bind()来改变事件对象的this指向