React中的事件
特别声明:为感谢社区广大朋友对小站的支持,自2019年10月1日至2019年11月11日开通年费VIP通道,年费价格为 ¥299.00元。如果您喜欢小站的内容,可以点击开通会员进行全站阅读。如果您对付费阅读有任何建议或想法,欢迎发送邮件至: airenliao@gmail.com!(^_^)
在大多的Web页面或Web应用程序中,构建UI仅仅是其中小小的一部分,其中有些U是纯静态的,但有些UI是会随着用户的操作带来相应变化的。比如,用户通过鼠标点击,键盘按下,视窗大小调整或一系列其他的手势和交互来触发。而这些我们往往称之为事件。在Web中处理事件都是交给JavaScript来完成,同样的,在React中也有相应的事件。在这一节开始,我们就来学习React中的事件。
你可能在DOM的世界中对事件的使用有一定的了解。如果没有,也不用担心,我们在开启探讨React的事件之前会对JavaScript中的事件做一个初步的了解。
JavaScript中的事件
Web页面或Web应用程序总是会提供一些控件给用户操作的。简单地说,用户做了一个操作,会发生什么。或者说,应用程序用什么方法让它们对已知的事件作出反应。
在开始之前,我们必须了解事件是什么?这个很简单,在Web中创建的所有东西都可以通过以下的语句来建模:
当(...)发生,做(...)?
在Web中我们可以用无数种不同的方法来填补这句话中的空白之处。第一个()
表示发生了什么?第二个()
描述相应的操作会发生什么?比如下面这些例子:
- 当(页面加载)完成时,请(播放视频)
- 当(点击)发生时,请(提交表单)
- 当(鼠标释放)时,请(放大图片)
- 当(按下删除键)时,请将此(列表项删除)
- 当(触摸手势)发生时,请将(旧照片过滤掉)
- 当(文件下载)完时,请(更新进度条)
这种模型适用于我们所有的编码。不过,事件只不过是一个信号。它表示刚刚发生了什么事。而这个事件是可以鼠标点击、键盘按下、触摸手势等。回到我们所说的事件模型中,模型的前半部分是我们所说的事件,后面部分是事件反应:
用到我们生活中来的话,有点类似于我们发送了一个信号,等事物接到这个信号就会做出一个对应的响应。而且在JavaScript中,事件又是非常重要的。如果用专业术语来描述的话,其包含两个部分:
- 事件侦听
- 事件做出的反应
这两个步骤看起来非常简单,但是不要忘记这是在JavaScript中处理。如果我们稍微走错了一步,都会给我们的应用程序带来巨大的创伤。
事件侦听
在JavaScript中有三种方式可以为DOM元素注册事件处理函数(即给元素添加事件侦听)。
addEventListener
最常见的就是通过addEventListener
来给目标元素添加事件侦听。比如:
myButton.addEventListener('click', function(){
alert('Hello, World!')
}, false)
HTMl属性
我们可以在HTML元素中添加事件:
<!-- HTML -->
<button onclick="alert('Hello, World!')">Click</button>
DOM元素属性
我们也可以直接给一个DOM元素属性添加相应的事件:
myButton.onclick = function(e){alert('Hello, World!')}
通常情况下,我们都习惯于使用addEventListener
来给目标元素(DOM元素)添加事件:
targetElement.addEventListener(eventName, eventHandler, false)
简单介绍一下其组成部分:
targetElement
:要侦听事件的元素或对象。通常是一个DOM元素,也可以是document
、window
或任何专门用于触发事件的对象eventName
:事件名称,在JavaScript中有关于事件的名称列表可以点击这里查阅eventHandler
:事件处理程序,就是程序要做的事情(比如用户点击了按钮,会发生什么事情?)- 事件冒泡或捕获:这是最后一个参数,在JavaScript中指的是事件冒泡或捕获
放到一起之后,他可能像下面这样:
btnEle.addEventListener('click',showMessage('大漠'), false)
const showMessage = (name) => {
alert(`Hello, ${name}~`)
}
事件捕获或冒泡
在JavaScript事件中还有一个很重要的概念,也比前面有关于事件的基础知识更为复杂,那就是事件捕获和事件冒泡。为了更好的帮助我们理解事件中有关于这两方面的概念,使用一个简单的示例来向大家阐述。
<!-- HTML -->
<!DOCTYPE html>
<html>
<body id="theBody" class="item">
<div id="one_a" class="item">
<div id="two" class="item">
<div id="three_a" class="item">
<button id="buttonOne" class="item">one</button>
</div>
<div id="three_b" class="item">
<button id="buttonTwo" class="item">two</button>
<button id="buttonThree" class="item">three</button>
</div>
</div>
</div>
<div id="one_b" class="item"></div>
</body>
</html>
如果我们用DOM树来描述上面的HTML结构的话,大致像下图这样:
假设用户点击了buttonOne
按钮,即触发了一个click
事件。很多同学都会认为click
事件是从目标元素buttonOne
开始触发,事实上并非如此,click
事件从文档的根开始(即window
)。如果用图来描述的话,如下;
click
事件从文档根(window
)开始,然后按照DOM树的路径一级一级往下寻找,直到触发click
事件的butttOne
元素(也称为事件目标)停止:
正如上图所示,事件所经过的路径是直的,它会通知该路径上的每个元素。如果该路径上有与当前事件匹配的元素,那么就会调用对应的事件处理程序。一旦事件达到目标,它就不会停止。不同的是,事件会往上移。事件路径上的每个元素都会得到其存在的通知。出现的任何事件处理程序也将被调用。
需要注意的是,事件在哪个位置启动并不重要,因为事件总是从文档的根开始,向下直接到达目标,然后返回根。在这样的一个过程中,从根开始向下寻找事件目标的过程被称为事件捕获阶段:
反过来,事件从目标元素向文档根元素的过程被称为事件冒泡阶段:
也就是说,当一个事件被触发时,会得到两次通知。每次监听事件时,我们都会选择要监听哪个阶段的事件。这是一个细节,我们可以给addEventListener
指定true
或false
来进行设置:
true
:表示在捕获阶段侦听事件false
:表示在冒泡阶段侦听事件
有的时候我们需要结束事件的生命周期。只需要在事件对象上使用stopPropagation
方法即可:
const handleClick = (e) => {
e.stopPropagation()
}
上面这些是JavaScript中事件的基础知识,如果你想了解更多有关于JavaScript事件相关的知识,可以阅读下面这些教程:
- DOM事件简介
- DOM事件的传播
- DOM事件模型
- 事件绑定的姿势
- UI Events
- Javascript Events Tutorial with Complete List of Events
- An Introduction To DOM Events
- Understanding Events in JavaScript
- Browser Events and Event Listeners
- Introduction to Events
- JavaScript Event Loop Explained
- Understanding Javascript Function Executions — Call Stack, Event Loop , Tasks & more
- The JavaScript Event Loop
- JavaScript 运行机制详解:再谈Event Loop
- Faster async functions and promises
- JavaScript. Event Loop and Promises
React中的事件
基于我们现有的JavaScript经验,你可能已经非常习惯使用事件。但是,在React中处理事件的方式和JavaScript有所不同。React没有直接针对DOM事件,而是将它们包装在自己的事件包装器中。在接下来的小节中,我将和大家一起探讨和学习React中事件相关的知识点。
创建事件
为了更好的和大家聊React中的事件,我们从一个简单的示例开始。该示例创建一个包含input
和button
的表单控件。input
可以输出你想要的文本内容,当input
输入一个值时,将触发一个事件(一般是onChange
)事件。另外,用户点击按钮时,也会触发一个事件(一般是onClick
)事件,该事件会调用一个函数,该函数会将文本框的内容(文本)反转。
该示例大致是这样工作的:
- 一个
input
,可以让用户输入想要的内容 - 当用户在
input
中输入值时,将会触发onChange
事件,它会调用一个handleChange()
函数,该函数用于设置input
的新状态 - 当用户点击“点击我”按钮时(
button
),会触发另一个事件,该事件会调用handleReverse()
函数,将输入框的文本反转
该示例的代码大致如下:
const App = () => {
const [inputVal, setInputVal] = React.useState('')
const [reversedText, setReversedText] = React.useState('')
const handleChange = e => setInputVal(e.currentTarget.value)
const handleClick = e => {
e.preventDefault()
setReversedText(inputVal.split("").reverse().join(""))
}
return (
<React.Fragment>
<form>
<div className="controle">
<input type="text" value={inputVal} onChange={handleChange} placeholder="输入你想要的内容" />
<button onClick={handleClick}><span>点击我</span></button>
</div>
</form>
<p>{reversedText}</p>
</React.Fragment>
)
}
上面示例中是React创建事件方式之一。如果你是使用类来创建的组件,那么组件中的创建事件方法可以像下面这样:
class MyComponent extends React.Component {
handleClick = () => {
// ...
}
render() {
return <button onClick={this.handleClick}>Click Me</button>
}
}
如果使用React Hooks来创建组件的话,除了上例中useState()
方法外,我们还可以使用useRef()
方法:
// React Hooks中使用useState()创建事件
class MyComponent = () => {
const handleClick = e => useState()
return <button onClick={handleClick}>Click Me</button>
}
// React Hooks中使用useRef()创建事件
class MyComponent = () => {
const handleChange = e => useRef()
return <button onClick={handleClick.current}>Clic
如需转载,烦请注明出处:https://www.w3cplus.com/react/react-event.html
如果文章中有不对之处,烦请各位大神拍正。如果你觉得这篇文章对你有所帮助,打个赏,让我有更大的动力去创作。(^_^)。看完了?还不过瘾?点击向作者提问!