React
React 事件机制
React 没有把事件直接绑定到真实 DOM 节点,而是实现了一套合成事件(SyntheticEvent)系统,统一代理所有事件。
一、合成事件与事件委托
React 将所有事件统一注册到根节点(React 17 之前是 document,17+ 是应用根容器),通过事件委托处理所有子节点的事件。
好处:
- 抹平浏览器差异,提供统一的事件接口
- 减少实际绑定的监听器数量,提升性能
二、与原生事件的区别
| 对比项 | 原生事件 | React 事件 |
|---|---|---|
| 命名 | 小写(onclick) | 驼峰(onClick) |
| 处理函数 | 字符串 ("handleClick()") | 函数引用({handleClick}) |
onFocus | 不冒泡 | 冒泡 |
| 阻止默认 | return false 可用 | 必须用 e.preventDefault() |
三、SyntheticEvent 常用属性
e.target // 触发事件的元素
e.currentTarget // 绑定事件处理函数的元素
e.nativeEvent // 原生 DOM 事件对象
e.preventDefault() // 阻止默认行为
e.stopPropagation() // 阻止事件冒泡注意:React 17 移除了事件池(event pooling),不再需要
e.persist(),可以在异步中安全访问事件属性。
四、支持的事件类型
| 分类 | 示例 |
|---|---|
| 鼠标 | onClick onMouseEnter onMouseLeave |
| 键盘 | onKeyDown onKeyUp |
| 表单 | onChange onSubmit onFocus |
| 触摸 | onTouchStart onTouchMove onTouchEnd |
| 剪贴板 | onCopy onCut onPaste |
五、使用建议
// 函数组件 —— 直接定义,无 this 问题
function Button() {
const handleClick = (e: React.MouseEvent) => {
e.preventDefault()
console.log(e.target)
}
return <button onClick={handleClick}>Click</button>
}避免在 JSX 中内联创建函数(如 onClick={() => fn()}),会在每次渲染时生成新函数引用,影响 memo 优化效果。
核心三句话
React 事件是对原生事件的跨浏览器封装;通过事件委托统一代理到根节点,减少监听器数量;命名用驼峰,阻止默认行为必须调用 e.preventDefault()。