React 中事件处理

不要问自己需要什么样的人生,而要问自己想要成为什么样的人。

我们从前面的学习知道一个 React 组件不仅仅只包含 DOM 结构的,还应该样式和 Javascript 逻辑的。这里我们认识逻辑构造之事件处理。

1. React 事件处理

这里列举了在 React 中事件的几种绑定处理方式:

React 复制代码
import React, { Component } from "react";

class App extends Component {
  render () {
    return (
      <div>
        <input/>
        <button onClick={ ()=>{ console.log("第一种事件绑定处理方式") }}>Add-1</button>
        <button onClick={ this.handleClick2 }>Add-2</button>
        <button onClick={ this.handleClick3 }>Add-3</button>
        <button onClick={ ()=>{ this.handleClick4() } }>Add-4</button>
      </div>
    )
  }

  handleClick2() {
    console.log("第二种事件绑定处理方式")
  }

  handleClick3 = ()=>{
    console.log("第三种事件绑定处理方式")
  }

  handleClick4 = ()=>{
    console.log("第四种事件绑定处理方式")
  }
}

export default App;

2. 事件绑定区别

这里重点说明下在事件和事件绑定绑定中 this 指向问题。

2.1 匿名函数

直接执行匿名函数,直接在 {} 中写事件函数表达式。

写法特点:

  • 适合逻辑少、简单表达式。如果处理逻辑过多、复杂 ,会导致结构不清晰,难维护,不推荐。
  • 事件内部 this 指向和外部一致,因为箭头函数没有 this 指向问题原则。

能直接访问:

  • 因为 onClick 后面表达式跟的是一个函数(箭头函数),这里事件内部 this 指向和外部一致。
react 复制代码
class App extends Component {
 // 定义属性
 value = 100

 render () {
  return (
    <div>
      <input/>
      <button onClick={ ()=>{ console.log("第一种事件绑定处理方式", this.value) }}>Add-1</button>
    </div>
  )
}

2.2 调用内部普通函数

写法特点:this 指向和外部不一致,需要用 bind 修正 this 指向,不推荐使用。

react 复制代码
<button onClick={ this.handleClick2 }>Add-2</button>
// 修正后:
<button onClick={ this.handleClick2.bind(this) }>Add-2</button>

handleClick2() {
  // 异常,需要通过改变 this 指向解决
  console.log("第二种事件绑定处理方式", this.value) 
}

不能直接访问:

这里访问类属性 this.value 会报错,我们可以打印出 this 看下它指向什么,结果会是:undefined。为什么 this 会丢失呢?记住一句话:函数中的 this 谁调用我,this 就指向谁。这里点完按钮后被 React 事件系统调用的,this 指向的应该是 React 事件系统。用于不会指向 App 这个实例。而这里它也没有指向 React 事件系统,而是丢了指向 undefined。哈哈哈....

2.3 调用内部箭头函数

写法特点:this 指向和外部一直,没有 this 指向问题,推荐使用。

React 复制代码
<button onClick={ this.handleClick3 }>Add-3</button>

handleClick3 = ()=>{
  console.log("第三种事件绑定处理方式", this.value)
}

这里是箭头函数,this 指向根本不关心谁调用的我,它永远保持与外部作用域一样的,它指向的 app 的实例。为什么箭头函数 this 指向就不关心谁调用的我呢?我也不知道.... 难到....

  • 箭头函数会自动改变 this 的指向???
  • 或者箭头函数不是改变 this 指向,而是引用上一个作用域的 this ???
  • 一个比较权威的解释是在箭头函数中,this 与封闭词法上下文的 this 保持一致。在全局代码中,它将被设置为全局对象。

2.4 执行匿名函数,调用其他内部函数

写法特点:this 指向和外部一直,没有 this 指向问题,符合谁调用我我指向谁。非常推荐使用这种写法,参数传递很方便。

react 复制代码
<button onClick={ ()=>{ this.handleClick4() } }>Add-4</button>
// 语法简写:
<button onClick={ ()=>this.handleClick4() }>Add-4</button>

// 有人说这里是因为你写成了箭头函数了吧,即使他不写成箭头函数也没关系,刚才讲的原理,符合谁调用我我指向谁。
handleClick4 = ()=>{
  console.log("第四种事件绑定处理方式", this.value)
}

整体有个问题: 要不要加小括号,不加不让他自己主动执行,点击系统会调用、加小括号执行函数。加小阔号主动执行,点击后不执行 undefined。

2.5 JS 中修正 this 指向方案

  • call:改变 this 指向,自动执行函数;
  • apply:改变 this 指向,自动执行函数;
  • bind:改变 this 指向,不会自动执行函数,需要手动加括号执行函数 ;
javascript 复制代码
var obj1 = {
  name: "obj1",
  getName() {
    console.log(this.name)
  }
}

var obj2 = {
  name: "obj2",
  getName() {
    console.log(this.name)
  }
}

// this.name 谁调用我我指向谁
obj1.getName() // 结果 obj1
obj2.getName() // 结果 obj2

// call, reply :修改 obj1 getName 中 this 指向 obj2
obj1.getName.call(obj2) // 结果 obj2
obj2.getName() // 结果 obj2

3. 总结事件处理

3.1 this 指向问题,记住两句话

  • 谁调用我我指向谁原则;
  • 箭头函数没有 this 指向问题;

3.2 React 事件绑定和原生事件绑定有什么区别?

React 中事件绑定没有绑定到具体的 DOM 节点(元素)身上。它采用的是一种事件代理的模式,绑定在根节点身上。绑定到每一个 DOM 节点身上是很消耗内存的。

React 模拟了一套事件冒泡机制,等冒泡到根节点上通过 target 事件源找到是那个元素真实触发的,然后从这个触发的元素到顶点所有节点都去查一查,有没有一个叫 onClick 属性,如果有就把这个 onClick 事件给执行了,完整模拟冒泡的流程,即模拟系统事件机制。其不需要考虑解绑、移除事件等,只有节点从页面中没了,onClick 根本就不会再有了,没有绑定只有节点没了 onClick 就没了。

3.3 Event 事件对象也是支持的

Event 对象,和普通浏览器一样,事件 handler 会被自动传入一个 event 对象,这个对象和普通的浏览器 event 对象所包含的方法和属性都基本一致。不同的是 React 中的 event 对象并不是浏览器提供的,而是它自己内部所构建的。它同样具有 event . stoppropagation、event.preventDefault 这种常用的方法。

相关推荐
crary,记忆4 小时前
微前端 - Module Federation使用完整示例
前端·react·angular
aiguangyuan11 小时前
浅谈 React Hooks
react·前端开发
whatever who cares2 天前
React hook之userReducer
react.js·react
aiguangyuan2 天前
React Hooks 基础指南
react·前端开发
aiguangyuan3 天前
React 项目初始化与搭建指南
react·前端开发
aiguangyuan3 天前
React 组件异常捕获机制详解
react·前端开发
aiguangyuan3 天前
深入理解 JSX:React 的核心语法
react·前端开发
aiguangyuan4 天前
React 基础语法
react·前端开发
aiguangyuan5 天前
React 核心概念与生态系统
react·前端开发
aiguangyuan5 天前
React 18 生命周期详解与并发模式下的变化
react·前端开发