当时,如果这对我来说是一个要求,我点击下面的按钮来获取我们州的数据。
btnfun(){
console.log(this);//undefined
console.log(this.state.data);//not undefined
}
为什么这里会出现这个问题呢? 因为btnfun()函数不是我们主动调用的,而是当按钮的暴风雨触发时typescript 事件绑定,react会在里面调用这个函数。 而react内部并不知道thishere指向哪里。
针对这个问题,我们给出三种解决方案:
解决方案1:在storm模式下使用bind进行绑定:
使用storm模式时,直接通过bind改变storm模式的方向,就像下面的代码:
<button onClick={this.btnfun.bind(this)}>button
btnfun(){
console.log(this);//undefined
console.log(this.state.data);//not undefined
}
这是当react内部调用我们的storm函数时,我们可以知道函数中的this指向哪里。
里面写的是一个解决方案,当我们遇到几个麻烦而不得不执行这个函数时,我们该怎么办呢? 我们可以采用以下方法进行优化。
constructor(props) {
super(props),
this.state={
data:'message'
},
this.btnfun=this.btnfun.bind(this)
}
我们可以把在storm模式下绑定this的操作放在构造函数中,这样前面使用的时候就可以直接使用this.btnfun了。
解决方案2:使用ES6 classfields句型
这些句型是为类定义属性的方式,称为类域句型。 由于这里使用了箭头函数作为形参typescript 事件绑定,所以无论如何都会在前一个作用域中查找箭头函数的this,而我们的storm方法的前一个作用域恰好是当前对象。
btnfun=() => {
console.log(this);//当前对象
console.log(this.state.data);//正常输出
}
这里请注意:
箭头函数体中的this对象是定义该函数的作用域所指向的对象,而不是该函数使用的作用域所指向的对象。
方案3:窃听时引入箭头功能(推荐)
虽然这些方法都是直接向onClickstorm传入一个箭头函数,然后在箭头函数中进行我们的操作,但是可以直接写在函数中或者调用外部函数。 这里的this就是箭头函数中的this,指向上一个作用域的this,这里也会发生隐式绑定,将this的指向变成我们想要的结果。
写法如下:
render() {
return (
<div>
<h2>React Demo</h2>
{/*<button onClick={this.btnfun}>button</button>*/}
<button onClick={() => this.btnfun()}>button</button>
</div>
)
}
btnfun() {
console.log(this);//undefined
console.log(this.state.data);//not undefined
}
风暴参数传递
在处理storm的时候,有时候会需要传递一些参数,最常见的就是事件对象。在jsx中,虽然在我们的storm模式下,事件对象是默认传递给我们的
如下代码所示:
render() {
return (
<div>
<h2>React Demo</h2>
<button onClick={this.btnclick}>button</button>
</div>
)
}
btnclick(e){
console.log(e);//打印event对象
}
}
如果我们还想传递一些其他参数怎么办? 还记得我们的this绑定问题的解决方案3,我们可以用这个方法来传递参数,包括事件对象(也就是箭头函数的参数)
看一下下面的需求:我们想要输出一个列表,但是点击单个li标签,复制对象的item和index,以及事件对象。
class App extends React.Component {
constructor(props) {
super(props),
this.state = {
movies: ['A', 'B', 'C', 'D']
}
this.btnclick = this.btnclick.bind(this)
}
render() {
return (
<div>
<h2>React Demo</h2>
<ul>
{
this.state.movies.map((item, index) => {
return <li onClick={(e) => {
this.liclick(item, index,e)
}}>{item}</li>
})
}
</ul>
</div>
)
}
liclick(item, index,e) {
console.log('li发生了点击', item, index,e);
}
}