React事件深入研究
在 React 中,事件处理与原生 DOM 事件处理有一些不同之处。以下是关于 React 事件的基本用法和注意事项。
1. 事件名是驼峰命名 🔗︎
React 的事件名采用 驼峰命名法,例如 onClick
、onMouseOver
等,而不是原生 HTML 的小写形式(如 onclick
)。
2. 传递函数作为事件处理程序 🔗︎
在 JSX 文件中,事件处理函数需要传递一个函数引用,而不是字符串。以下是一个简单的示例:
import React, { Component } from 'react';
class Hello extends Component {
clickHandler(e) {
e.preventDefault();
console.log("The link was clicked.");
}
render() {
return (
<div>
<button onClick={this.clickHandler}>点我</button>
</div>
);
}
}
export default Hello;
3. 阻止默认行为 🔗︎
在 React 中,阻止默认行为需要调用 e.preventDefault()
,不能通过 return false
来实现。
4. 合成事件对象 🔗︎
React 的事件对象 e
是一个 合成事件对象,它封装了原生事件对象,并提供了跨浏览器的一致性支持。
合成事件对象的属性 🔗︎
以下是合成事件对象的主要属性:
boolean bubbles; // 是否冒泡
boolean cancelable; // 是否可以取消默认行为
DOMEventTarget currentTarget; // 当前事件处理程序绑定的 DOM 元素
boolean defaultPrevented; // 默认行为是否已被阻止
number eventPhase; // 事件传播阶段
boolean isTrusted; // 事件是否由用户触发
DOMEvent nativeEvent; // 原生事件对象
void preventDefault(); // 阻止默认行为
boolean isDefaultPrevented(); // 判断默认行为是否被阻止
void stopPropagation(); // 阻止事件冒泡
boolean isPropagationStopped(); // 判断事件冒泡是否被阻止
DOMEventTarget target; // 触发事件的原始 DOM 元素
number timeStamp; // 事件发生的时间戳
string type; // 事件类型
5. 处理 this
指向问题 🔗︎
在类组件中,事件处理函数的 this
默认指向 undefined
。如果需要让 this
指向当前组件实例,可以使用以下几种方法:
方法 1:使用 bind
绑定 this
🔗︎
<button onClick={this.clickHandler.bind(this)}>点我</button>
方法 2:使用箭头函数定义事件处理函数 🔗︎
clickHandler = (e) => {
e.preventDefault();
console.log("The link was clicked.");
}
方法 3:在 JSX 中使用箭头函数 🔗︎
<button onClick={(e) => this.clickHandler(e)}>点我</button>
6. 传递参数给事件处理函数 🔗︎
如果需要向事件处理函数传递额外参数(如 ID),可以使用以下两种方式:
方式 1:使用箭头函数 🔗︎
<button onClick={(e) => this.clickHandler(this.id, e)}>Delete Row</button>
方式 2:使用 bind
🔗︎
<button onClick={this.clickHandler.bind(this, this.id)}>Delete Row</button>
7. 异步访问合成事件对象 🔗︎
由于 React 出于性能考虑,在事件处理函数结束后会将合成事件对象的所有属性置为 null
,因此无法通过异步方式直接访问这些属性。
示例问题 🔗︎
clickHandler(id, e) {
e.preventDefault();
console.log("The link was clicked.");
console.log(id);
setTimeout(function() {
console.log(e.bubbles); // 输出 null
}, 0);
}
解决方案:调用 e.persist()
🔗︎
通过调用 e.persist()
,可以保留合成事件对象的属性值,使其在异步代码中可用。
clickHandler(id, e) {
e.preventDefault();
console.log("The link was clicked.");
console.log(id);
e.persist(); // 保留事件对象
setTimeout(function() {
console.log(e.bubbles); // 输出 true
}, 0);
}
8. 支持捕获阶段触发事件 🔗︎
如果需要在捕获阶段触发事件,可以在事件名称后加上 Capture
,例如:
<button onClickCapture={this.clickHandler}>点我</button>
这会在事件捕获阶段触发 clickHandler
,而不是在冒泡阶段。
Be the first to know when I post cool stuff
Subscribe to get my latest posts by email.
Thanks for signing up! Check your email to confirm your subscription.
Whoops, we weren't able to process your signup.