# react 中的事件处理

96 阅读3分钟

react 中的事件处理

今天我们说一下 react 中的事件处理。我们还是基于上一篇博客写的案例来说。

上篇博客案例代码

    <!-- 此处必须写 text/babel -->
    <script type="text/babel">

        // 创建组件
        class Demo extends React.Component {
        
            myRef = React.createRef()
            myRef2 = React.createRef()

            // 展示左侧数据
            showData = () => {
                alert(this.myRef.current.value)
            }

            showData2 = () => {
                alert(this.myRef2.current.value)
            }

            render() {
                return (
                    <div>
                        <input ref={this.myRef} type="text" placeholder="请输入文字"></input>
                        <button onClick={this.showData}>点击我弹出左侧内容</button> <br />
                        <input ref={this.myRef2} onBlur={this.showData2} type="text" placeholder="右侧数据" />
                    </div>
                )
            }
        }
        // 渲染组件
        ReactDOM.render(<Demo />, document.getElementById("app"))
    </script>

事件处理

上一篇博客我们看到哈,有一个按钮,通过 onClick 来实现了点击事件,在点击事件里面获取到了 ref 绑定的 dom 节点进行处理。我们发现一点哈,就是在 react 中,绑定事件的写法是 onClick ,但是 js 原生的是 onclick ,这是为啥呢?其实 react 的点击事件 onClick 是对 js 原生点击事件 onclick 进行了一次封装,是一个自定义(合成)事件,而不是原生的 dom 事件,他的目的是为了更好的兼容性,其实不光是 onClick,像是 onBlur,onChange 都是二次封装过后的写法,其实有一个规律,就是 react 中使用 js 相对应的原生事件,都是采用驼峰的方式编写,直接 onclick 是会报错的,记住就可以了哈!

然后在之前开发的过程中,比如我们写一个 ul 列表。

<ul>
	<li></li>
	<li></li>
	<li></li>
</ul>

我们想给列表项添加点击事件的时候,一般不是直接加载 li 标签上,而是写在 ul 标签上,对吧?那么 react 也是一样的,react 中的事件是通过事件委托方式处理的(委托给组件最外层元素)。事件委托的原理是事件冒泡,他的目的就是提高效率。知道就好哈。

在学习 refs 的时候有一个事情忘记说了,就是官方给出了一个建议,就是说在组件开发过程中啊,要尽可能的减少 refs 的使用。

在这里插入图片描述

看我们之前写的案例代码。

<input ref={this.myRef} type="text" placeholder="请输入文字"></input>
<button onClick={this.showData}>点击我弹出左侧内容</button> <br />
<input ref={this.myRef2} onBlur={this.showData2} type="text" placeholder="右侧数据" />

点击 按钮 获取 第一个input 的时候为了获取 input 的值,我们在 input 标签上面使用了 ref。 第二个 input 失去焦点为了获取 input 的值,我们也使用了 refs 。

那能不能为了减少使用 refs 优化一下呢? 答案是可以的。

react 可以 通过 event.target 得到发生事件的 DOM 元素对象。

啥意思呢,点击按钮获取第一个输入框的值没办法套用这句话修改代码。但是第二个 input 输入框是可以的。

我们去掉第二个输入框的 ref 属性,不设置了。

<input onBlur={this.showData2} type="text" placeholder="右侧数据" />

然后在失去焦点的时候,我们调用了 showData2 方法,那这个回调方法有没有返回值呢?答案是有的,啥呢? —— event。 那这个 event 是什么?其实都知道是吧,event 是触发的事件,在 event 里面有一个 target,这是啥呢? target 就是触发事件的事件源

我们打印一下 event.target 。

            // 失去焦点事件
            showData2 = (event) => {
                console.log(event.target)
            }

保存看一下结果。

在这里插入图片描述

诶,我们看到 是在 第二个 input 上面触发的失去焦点事件吧?所以说这个失去焦点事件的事件源就是 第二个输入框 的节点,那我们拿到节点了,就可以获取值了吧?

    <!-- 此处必须写 text/babel -->
    <script type="text/babel">

        // 创建组件
        class Demo extends React.Component {

            // 创建 ref 容器
            myRef = React.createRef()
            myRef2 = React.createRef()

            // 展示左侧数据
            showData = () => {
                alert(this.myRef.current.value)
            }

            // 失去焦点事件
            showData2 = (event) => {
                // event是事件 , event.target 是事件源
                alert(event.target.value)
            }

            render() {
                return (
                    <div>
                        <input ref={this.myRef} type="text" placeholder="请输入文字"></input>
                        <button onClick={this.showData}>点击我弹出左侧内容</button>
                        <input onBlur={this.showData2} type="text" placeholder="右侧数据" />
                    </div>
                )
            }
        }
        // 渲染组件
        ReactDOM.render(<Demo />, document.getElementById("app"))
    </script>

看效果,也是可以正常使用的

在这里插入图片描述

这样我们就少用了一个 ref 对吧?OK,今天的内容就是这样子的。

总结

  • 通过 onXX 属性指定时间处理函数(注意大小写)。 —— 为了更好的兼容性。
    1. react 使用的是自定义(合成)事件,而不是使用原生的DOM事件。
    2. react 中的事件是通过事件委托方式处理的(委托给组件最外层元素)。 —— 事件委托的原理是事件冒泡,为了高效。
  • 通过 event.target 得到发生事件的 DOM 元素对象。 —— 不要过渡的使用 ref,发生事件的元素正好是我要操作的元素时可以省略。

完成了,干饭去!

在这里插入图片描述

【本博客相关代码资料】:我是𝒆𝒅. 的 gitee