FumadocsZDecode
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()

On this page