React事件处理方法中this指向为undefined的四种解决方案:
话不多说,先上代码
如图所示:点击’-‘按钮数字减一,并打印出当前数字,点击’+'按钮数字加一,并打印出当前数字
<div id="root"></div>
<script src="js/react.development.js"></script>
<script src="js/react-dom.development.js"></script>
<script src="js/babel.min.js"></script>
//此处的js我是从react官网直接下载的
<script type="text/babel">
class XzCart extends React.Component{
constructor(p) {
super(p)
this.state={buyCount:p.num}
// this._f2=this._f2.bind(this)
// this._f1=this._f1.bind(this)
}
_f1(){
let buyCount=this.state.buyCount*1-1
this.setState({buyCount},()=>{
// setState是异步执行的,此处是在"数据/界面修改完成"后调用
console.log(this.state.buyCount)
})
}
_f2(){
let buyCount=this.state.buyCount*1+1
this.setState({buyCount},()=>{
console.log(this.state.buyCount)
})
}
render(){
//return的是JSX片段
return(
<div>
<button onClick={this._f1}>-</button>
<span className="cart">{this.state.buyCount}</span>
<button onClick={this._f2}>+</button>
</div>
)
}
}
let e=<XzCart num="5"/>
ReactDOM.render(e,root)
</script>
此处点击按钮的时候会出现this指向undefined错误
解决方案
方案1:
行间定义事件后面使用bind绑定this
onClick={this._f1bind(this)}
此方案有一个缺点,每次点击都会创建一个函数的副本
代码如下,将return部分的jsx代码对应的button点击事件进行修改
return(
<div>
<button onClick={this._f1.bind(this)}>-</button>
<span className="cart">{this.state.buyCount}</span>
<button onClick={this._f2.bind(this)}>+</button>
</div>
)
方案2:
在构造函数内部声明this指向
此方案为官方推荐方法,代码如下,只需修改constructor部分
constructor(p){
super(p)
this.f1=this._f1.bind(this)
this.f2=this._f2.bind(this)
}
方案3:
行间定义事件使用箭头函数
onClick={()=>{this._f1()}},代码如下,修改return部分
return(
<div>
<button onClick={()=>{this._f1()}}>-</button>
<span className="cart">{this.state.buyCount}</span>
<button onClick={()=>{this._f2()}}>+</button>
</div>
)
方案4:
声明事件时将事件等于一个箭头函数
_f1=()=>{
//把事件处理函数声明为箭头函数
}
代码如下:将事件处理函数声明为箭头函数
_f1(){
let buyCount=this.state.buyCount*1-1
this.setState({buyCount},()=>{
// setState是异步执行的,此处是在"数据/界面修改完成"后调用
console.log(this.state.buyCount)
})
}
_f2(){
let buyCount=this.state.buyCount*1+1
this.setState({buyCount},()=>{
console.log(this.state.buyCount)
})
}
我最喜欢这个方案四了,当然你们喜欢哪个看个人想法了
对了 这个我给大家提醒一下,npm的国内镜像有新通知了 镜像的地址换了,之前的镜像地址将要作废 大家记得换一下哈