React中的事件

特别声明:小站已开通年费VIP通道,年费价格为 ¥365.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元素,也可以是documentwindow或任何专门用于触发事件的对象
  • 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指定truefalse来进行设置:

  • true:表示在捕获阶段侦听事件
  • false:表示在冒泡阶段侦听事件

有的时候我们需要结束事件的生命周期。只需要在事件对象上使用stopPropagation方法即可:

const handleClick = (e) => {
    e.stopPropagation()
}

上面这些是JavaScript中事件的基础知识,如果你想了解更多有关于JavaScript事件相关的知识,可以阅读下面这些教程:

React中的事件

基于我们现有的JavaScript经验,你可能已经非常习惯使用事件。但是,在React中处理事件的方式和JavaScript有所不同。React没有直接针对DOM事件,而是将它们包装在自己的事件包装器中。在接下来的小节中,我将和大家一起探讨和学习React中事件相关的知识点。

创建事件

为了更好的和大家聊React中的事件,我们从一个简单的示例开始。该示例创建一个包含inputbutton的表单控件。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
剩余80%内容付费后可查看

如需转载,烦请注明出处:https://www.w3cplus.com/react/react-event.html

如果文章中有不对之处,烦请各位大神拍正。如果你觉得这篇文章对你有所帮助,打个赏,让我有更大的动力去创作。(^_^)。看完了?还不过瘾?点击向作者提问!

赏杯咖啡,鼓励他创作更多优质内容!
返回顶部