react中事件处理时为什么要手动绑定this?

react中事件处理时为什么要手动绑定this?

之前一直没有深入研究过这个问题, 重读react文档后仔细研究了一下这个问题.
我们都知道普通js函数中this的指向是调用函数的对象,而且是离谁近指向谁.
非严格模式下, this默认指向全局对象window
严格模式下, this为undefined

而箭头函数是在定义时就已经确定好了this的指向, 不会根据谁调用它而改变

基于此, 在react中为什么直接 onClick={this.handleClick} 不可以呢?

根本原因是react中的dom是虚拟dom, JSX是React.createElement(component, props, ...children) 的语法糖, 在我们调用事件函数的时候其实这段代码

render(){
    return (<a href="#" onClick={this.handleClick}>click me </a>
})

是被解析成

render(){
   return React.createElement(
    "a", 
    { onClick: this.handleClick}, 
    "click me"
    );
   }

这样的代码的, onClick = {function} 中的onClick本身就是一个"中间变量", this.handleClick又作为一个callback传给另一个函数, 这时候this就丢失了.举个简单例子

class Cat {
 sayThis () {
    console.log(this); 
  }

 exec (cb) {
    cb();
  }

 render () {
    this.exec(this.sayThis);
  }
}
const cat = new Cat();
cat.render(); 

其中的sayThis又作为参数传给exec作为一个回调函数时, this已经丢失了
因此我们要在react的事件处理中进行bind this

复杂来说, 就要讲到react合成事件了

react合成事件
  • 所有事件挂载到document上
  • even不是原生的, 是合成事件对象
  • 和Vue事件不同, 和DOM事件也不同
        event.preventDefault() // 阻止默认行为
        event.stopPropagation() // 阻止冒泡
        console.log('target', event.target) // 指向当前元素,即当前元素触发
        console.log('current target', event.currentTarget) // 指向当前元素,假象!!!

        // 注意,event 其实是 React 封装的。可以看 __proto__.constructor 是 SyntheticEvent 组合事件
        console.log('event', event) // 不是原生的 Event ,原生的 MouseEvent
        console.log('event.__proto__.constructor', event.__proto__.constructor)

        // 原生 event 如下。其 __proto__.constructor 是 MouseEvent
        console.log('nativeEvent', event.nativeEvent)
        console.log('nativeEvent target', event.nativeEvent.target)  // 指向当前元素,即当前元素触发
        console.log('nativeEvent current target', event.nativeEvent.currentTarget) // 指向 document !!!

        // 1. event 是 SyntheticEvent ,模拟出来 DOM 事件所有能力
        // 2. event.nativeEvent 是原生事件对象
        // 3. 所有的事件,都被挂载到 document 上
        // 4. 和 DOM 事件不一样,和 Vue 事件也不一样

某元素触发事件后 -> 冒泡到document上(合成事件都绑定到document上) -> 实例化成统一的react event -> dispatchEvent将事件交由对应的处理器执行

思考: 为什么要使用合成事件机制
  • 更好的兼容性和跨平台
  • 挂载到document上, 减少内存消耗, 避免频繁解绑
  • 方便事件的统一管理

那么, 相比于onClick={() => this.handleClick}

onClick={this.handleClick}
handleClick = () => {}
两种绑定this的方法, 哪种更好呢?

使用第一种方法绑定, 会创建一个新函数, 那么每次组件更新时, onClick都会传一个新的箭头函数实例, 影响性能.
因此第二种方法更好一些

参考1
参考2

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值