ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

为什么React事件处理函数必须使用Function.bind()绑定this

2020-01-29 12:02:07  阅读:216  来源: 互联网

标签:Function 事件处理 obj 指向 bind 绑定 React testLog tmp


React官网学习Handling Events这一章有如下代码

class Toggle extends React.Component {
  constructor(props) {
    super(props);
    this.state = {isToggleOn: true};

    // This binding is necessary to make `this` work in the callback
    this.handleClick = this.handleClick.bind(this);
  }

  handleClick() {
    this.setState(prevState => ({
      isToggleOn: !prevState.isToggleOn
    }));
  }

  render() {
    return (
      <button onClick={this.handleClick}>
        {this.state.isToggleOn ? 'ON' : 'OFF'}
      </button>
    );
  }
}

ReactDOM.render(
  <Toggle />,
  document.getElementById('root')
);

注意到在Toggle类的构造函数constructor类中,有一句注释:“This binding is necessary to make this work in the callback”,即在构造函数中,利用Function.bind()函数将类中已有的handleClick函数再次绑定了一下this。
对于这个做法,官网给出的注释是:

在这里插入图片描述

这段话说了看似说了很多,其实就两点:

1、如果你不绑定this.handleClick方法,那么在事件发生并且精确调用这个方法时,方法内部的this会丢失指向。
2、这不是React的原因,这是JavaScript中本来就有的。如果你传递一个函数名给一个变量,然后通过在变量后加括号()来调用这个方法,此时方法内部的this的指向就会丢失。

这一段点明了为什么要在构造函数中绑定this,因为JavaScript中确实有这么一个陷阱。具体是怎么样的呢?进行了一下测试:

let obj = {
    tmp:'Yes!',
    testLog:function(){
        console.log(this.tmp);
    }
};
obj.testLog();
1234567

为了便于为学习ES6的童鞋理解以及说明这是JavaScript中的陷阱而非React所特有,这里使用字面量表达式声明对象。

经过测试,这样使用obj中的testLog方法时,this指向obj,能够正常输出tmp属性:

在这里插入图片描述

现在修改一下代码:

let obj = {
    tmp:'Yes!',
    testLog:function(){
        console.log(this.tmp);
    }
};
let tmpLog = obj.testLog;
tmpLog();
12345678

注意到现在没有直接调用obj对象中的testLog方法,而是使用了一个中间变量tmpLog过渡,当使用括号()调用该方法时,方法中的this丢失了指向,会指向window,进而window.tmp未定义就是undefined:

{% asset_img 20190606225247362.png img %}在这里插入图片描述

说了这么多,跟React事件处理函数的绑定有什么关系呢?

前面讲过,React跟原生JavaScript的事件绑定区别有两点,其中第二点就是:

即在React(或者说JSX)中,传递的事件参数不是一个字符串,而是一个实实在在的函数:
在这里插入图片描述

这样说,React中的事件名(上图中的onClick)就是我所举例子中的中间变量,React在事件发生时调用onClick,由于onClick只是中间变量,所以处理函数中的this指向会丢失,为了解决这个问题,我们需要在实例化对象的时候,需要在构造函数中绑定this,使得无论事件处理函数如何传递,它的this的指向都是固定的,固定指向我们所实例化的对象。


https://www.cnblogs.com/DM428/p/7777539.html Tonited 发布了9 篇原创文章 · 获赞 9 · 访问量 2302 私信 关注

标签:Function,事件处理,obj,指向,bind,绑定,React,testLog,tmp
来源: https://blog.csdn.net/weixin_43553694/article/details/104105561

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有