一、React 事件的本质
在 React 中,事件不是原生的 DOM 事件,而是 合成事件(SyntheticEvent)。
React 自己实现了一套跨浏览器的事件系统,用于封装原生事件,让你在所有浏览器中都能一致地使用。
也就是说:
<button onClick={handleClick}>点击</button>
这里的 onClick 并不是直接绑定在 DOM 上的,而是 React 统一注册的。
二、React 事件的绑定方式
在 JSX 中以驼峰命名方式绑定
React 事件属性用 小写 on + 大写首字母事件名 的形式,例如:
-
onClick
-
onChange
-
onMouseEnter
-
onSubmit
示例:
function App() {function handleClick() {console.log("按钮被点击");}return <button onClick={handleClick}>点我</button>;
}
注意:不能写成 onclick="handleClick()"(那是 HTML 写法)
传参的写法
当你要给事件传参时,需要用箭头函数包一下:
<button onClick={() => handleClick(id)}>删除</button>
或者绑定时:
<button onClick={handleClick.bind(this, id)}>删除</button>
类组件中的事件
在类组件中,你可以这样写:
class App extends React.Component {handleClick = (event) => {console.log('点击事件', event);};render() {return <button onClick={this.handleClick}>点我</button>;}
}
箭头函数写法可以自动绑定 this,不然要在构造函数中 this.handleClick = this.handleClick.bind(this)。
React 合成事件对象(SyntheticEvent)
React 事件的回调会接收一个合成事件对象:
function handleClick(e) {console.log(e); // SyntheticEventconsole.log(e.nativeEvent); // 原生事件
}
特点:
-
兼容所有浏览器;
-
在事件池中复用(异步中要先调用 e.persist() 保留事件);
示例:
function handleClick(e) {e.preventDefault(); // 阻止默认行为e.stopPropagation(); // 阻止冒泡
}
事件冒泡与捕获
React 的事件默认是冒泡阶段触发的。
如果要监听捕获阶段,加上 Capture:
<div onClickCapture={handleCapture}><button onClick={handleBubble}>点我</button>
</div>
执行顺序:
-
捕获阶段:父的 onClickCapture
-
冒泡阶段:子的 onClick
-
冒泡阶段:父的 onClick
React 事件与原生事件的区别总结
对比项 | React事件 | 原生DOM事件 |
---|---|---|
注册方式 | JSX属性(onClick) | addEventListener |
事件名 | 驼峰命名 | 小写 |
对象类型 | SyntheticEvent | Event |
绑定位置 | 统一代理到 root(React 18是 root container) | 绑定到具体元素 |
跨浏览器兼容 | ✅ | ❌ |
阻止默认行为 | e.preventDefault() |
event.preventDefault() |
React 18 的变化
React 18 开始,事件代理不再统一绑定到 document,而是绑定到 React 根节点(root)。
这样多个 React 应用可以共存,互不影响。
常见事件示例
<input onChange={(e) => console.log(e.target.value)} />
<form onSubmit={(e) => e.preventDefault()} />
<div onMouseEnter={() => console.log('鼠标进入')} />