React事件绑定时this指向问题解决以及事件传参

React事件绑定中的this指向问题

当时如果这是我有一个需求,我点击以下按钮,来获取我们state中的数据。

btnfun(){
    console.log(this);//undefined
    console.log(this.state.data);//not undefined
}

这里为什么会出现这个问题呢?因为btnfun()函数并不是我们主动调用的,而是当触发button的事件时,react内部再去调用这个函数。而react的内部时不知道这里的this是指向哪里的。

为了解决这个问题,我们给出了三种解决方案:

方案一:使用bind为事件方法绑定this:

在使用事件方法时直接通过bind改变事件方法的指向,就像如下代码一样:

 <button onClick={this.btnfun.bind(this)}>button</button>
   btnfun(){
      console.log(this);//undefined
      console.log(this.state.data);//not undefined
    }

这是当react内部调用我们的事件函数时,就可以得知函数中的this指向何处。

上面的写法是一解决方案,但是当我们有 若干个事件都要去执行这个函数怎么办呢?我们可以使用下面这种方式进行优化。

 constructor(props) {
      super(props),
      this.state={
        data:'message'
      },
      this.btnfun=this.btnfun.bind(this)
    }

我们可以将为事件方法绑定this的操作放在构造器里,这样在后面使用时就直接使用this.btnfun 即可。

方案二:使用ES6的class fields语法

​ 这种语法是给类定义属性的方法,称之为class field语法。因为这里在赋值时使用了箭头函数,而箭头函数的this在任何情况下都会去上一个作用域中查找,而我们事件方法的上一个作用域恰巧就是当前的对象。

 btnfun=() => {
      console.log(this);//当前对象	 	
      console.log(this.state.data);//正常输出
    }

这里须知:

箭头函数体内的this对象,就是定义该函数时所在的作用域指向的对象,而不是使用时所在的作用域指向的对象。

方案三:事件监听时传入箭头函数(推荐)

​ 这种方式其实就是当给onClick事件中直接传入一个箭头函数,然后在箭头函数中进行我们的操作,可以直接写在函数中,也可以调用外部的函数。这里的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
    }

事件参数传递

在处理事件时,有时候也会有一些需要传递的参数,最常见的就是event对象。在jsx中其实在我们的事件方法中默认就给我们传递了event对象

如下代码所示:

  render() {
      return (
        <div>
          <h2>React Demo</h2>
          <button onClick={this.btnclick}>button</button>
        </div>
      )
    }
    btnclick(e){
      console.log(e);//打印event对象
    }
  }

​ 但是如果我们还想要传递一些其他的参数呢?还记得我们this绑定问题的方案3吗,我们可以使用此方法进行参数的传递,包括event对象(是箭头函数的参数)

看以下需求:我们想要输出一个列表,并且点击单个li标签,打印对象的item和index以及event对象。

  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);
    }
  }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值