闽公网安备 35020302035485号
<button onClick={(e) => console.log(e)}>点我一下</button>
看起来很普通对吧?但你有没有想过:.React 的事件性能为什么这么高?
| 角色 | 是什么? | 跟事件有啥关系? |
|---|---|---|
| 虚拟 DOM | React 内部描述 UI 的 JS 对象 | ❌ 跟事件没关系! |
| 原生 DOM | 浏览器中的真实标签元素 | ✅ 事件最终触发的地方 |
| 合成事件(SyntheticEvent) | React 封装的“代理事件对象” | ✅ 真正传给你的 e |
function App() {
return (
<button
onClick={(e) => {
console.log('e:', e); // 合成事件
console.log('e.nativeEvent:', e.nativeEvent); // 原生事件
console.log('e.target:', e.target); // DOM 节点
}}
>
点我!
</button>
);
}
✅ 合成事件有啥用?3.最重要:可以被 React 优化和“回收”!
<button
onClick={(e) => {
setTimeout(() => {
console.log(e.target); // ❌ 报错或 undefined
}, 1000);
}}
>
异步点击
</button>
输出结果可能是:null
{}
Cannot read properties of null
因为你这个 e,早就被 React 还给事件池啦!✅ 方法 1:同步解构赋值
onClick={(e) => {
const target = e.target;
setTimeout(() => {
console.log(target); // 安全!
}, 1000);
}}
✅ 方法 2:调用 e.persist()
onClick={(e) => {
e.persist(); // 阻止事件回收
setTimeout(() => {
console.log(e.target); // OK
}, 1000);
}}
e.persist() 就是告诉 React: “哥别收回这个事件对象,我要留着用!”