react 事件机制
一 前言 我们来一起探讨一下React事件原理,这篇文章,我尽量用通俗简洁的方式,把React事件系统讲的明明白白。 我们讲的react版本是16.13.1 , v17之后react对于事件系统会有相关的改版,文章后半部分会提及。 老规矩,在正式讲解react之前,我们先想想这几个问题(如果我是面试官,你会怎么回答?): 我们写的事件是绑定在dom上么,如果不是绑定在哪里? 为什么我们的事件不能绑定给组件? 为什么我们的事件手动绑定this(不是箭头函数的情况) 为什么不能用 return false 来阻止事件的默认行为? react怎么通过dom元素,找到与之对应的 fiber对象的? onClick是在冒泡阶段绑定的? 那么onClickCapture就是在事件捕获阶段绑定的吗? 必要的知识概念 在弄清楚react事件之前,有几个概念我们必须弄清楚,因为只有弄明白这几个概念,在事件触发阶段,我们才能更好的理解react处理事件本质。 我们写在JSX事件终将变成什么? 我们先写一段含有点击事件的react JSX语法,看一下它最终会变成什么样子? class Index extends React.Component{ handerClick= (value) => console.log(value) render(){ return <div> <button onClick={ this.handerClick } > 按钮点击 </button> </div> } } 经过babel转换成React.createElement形式,如下: 最终转成fiber对象形式如下: fiber对象上的memoizedProps 和 pendingProps保存了我们的事件。 什么是合成事件? 通过上一步我们看到了,我们声明事件保存的位置。但是事件有没有被真正的注册呢?我们接下来看一下: 我们看一下当前这个元素<button>上有没有绑定这个事件监听器呢? button上绑定的事件 我们可以看到 ,button上绑定了两个事件,一个是document上的事件监听器,另外一个是button,但是事件处理函数handle,并不是我们的handerClick事件,而是noop。 noop是什么呢?我们接着来看。 原来noop就指向一个空函数。 然后我们看document绑定的事件 可以看到click事件被绑定在document上了。 接下来我们再搞搞事情😂😂😂,在demo项目中加上一个input输入框,并绑定一个onChange事件。睁大眼睛看看接下来会发生什么? class Index extends React.Component{ componentDidMount(){ console.log(this) } handerClick= (value) => console.log(value) handerChange=(value) => console.log(value) render(){ return <div style={{ marginTop:'50px' }} > <button onClick={ this.handerClick } > 按钮点击 </button> <input placeholder="请输入内容" onChange={ this.handerChange } /> </div> } } 我们先看一下input dom元素上绑定的事件 ...