React中的事件处理为什么要bind this?

个人总结:

 

问: 请给我讲一下React中的事件处理为什么要bind this?

 

 

答: 好的,比如说我写了一个类组件,有个onClick属性 ,onClick={ this.fun },如果不bind肯定是不行的,下面讲一下为什么要bind this:

 

    首先我们知道React是通过创建虚拟DOM 然后将虚拟DOM生成真实的DOM 最后插入到页面中,

    而React生命周期中render方法的作用就是将虚拟DOM渲染成真实DOM

     看一下这篇文章 https://github.com/hujiulong/blog/issues/4

    这里提到了render的实现 render将"on+大写字母"开头的事件属性 转化为"on+小写字母"开头的属性 ,并生成真实DOM,生成真实DOM的同时

    把这个函数赋值过去。  

  ( 这篇文章只是一个简要的示例,实际情况更为复杂)

 

  在JSX语法中: onClick={  function  }  onClick这个属性本身只是一个"中间变量"。将函数赋值给onClick这个中间变量,后面要进行JSX语法转化,将JSX组件转换成Javascript对象,进而转换成真实DOM。

把onClick作为中间变量,指向一个函数的时候,后面的一系列处理中,使用onClick这个中间变量所指向的函数,里面的this会自然丢失掉了,不是再指向react组件实例了。

 

 

预备知识点:JS中的this是由函数调用者调用的时候决定的。 

   obj:{

       fun:function(){ console.log(this) }

      } 

  obj.fun()   //obj

 

let var = obj.fun()

  var()      // window||undefined

 

   在类组件的render函数中 将函数fun赋给真实的属性的时候 有点类似于做了这样的操作:

class Cat {
 sayThis () {
 console.log(this); // 这里的 `this` 指向谁?
  }

 exec (cb) {
 cb();
  }

 render () {
 this.exec(this.sayThis);
  }
}
const cat = new Cat();
cat.render(); // 输出结果是什么?

 

当把一个函数作为callback传递给另一个函数的时候,这个函数的this一定是会丢失的,

 

相当于是 let var = function () { ..} ; var();

所以会出现这种问题。

 

 

延伸一下,为什么React没有自动的把bind集成到render方法中呢?

答:因为render函数会被多次调用,每次都要bind会影响性能,所以官方建议你自己在constructor中手动bind达到性能优化。

posted @ 2018-11-11 23:27  hh9515  阅读(4275)  评论(2编辑  收藏  举报