React中的事件-合成事件与原生事件
2024-02-27 React
在 React 应用开发中,事件处理是实现交互的基础。React 通过合成事件(Synthetic Events)和原生事件(Native Events)提供了一套强大的事件处理机制。理解这两种事件的区别和适用场景,对于编写高效、可维护的 React 应用至关重要。
合成事件 (Synthetic Events) #
合成事件是 React 为了保证跨浏览器兼容性和性能优化而创建的一种事件系统。它们模拟了原生事件,但提供了更一致的接口和行为。合成事件在 React 的虚拟 DOM 层上处理,允许 React 在事件处理和更新中进行优化。
特点: #
- 跨浏览器兼容性:合成事件屏蔽了不同浏览器之间的差异,提供了统一的接口。
- 批处理:在合成事件中,
setState
调用是异步的,React 会将多次状态更新合并为一次重新渲染。 - 事件委托:合成事件使用事件委托机制,将所有事件处理器绑定到根元素上,从而减少事件处理器的数量,提高性能。
常见合成事件: #
- 鼠标事件:
onClick
,onDoubleClick
,onMouseDown
,onMouseUp
,onMouseMove
,onMouseEnter
,onMouseLeave
- 表单事件:
onChange
,onInput
,onSubmit
,onFocus
,onBlur
- 键盘事件:
onKeyDown
,onKeyPress
,onKeyUp
- 触摸事件:
onTouchStart
,onTouchMove
,onTouchEnd
- 滚动事件:
onScroll
- 拖拽事件:
onDrag
,onDragStart
,onDragEnd
,onDragOver
,onDragEnter
,onDragLeave
原生事件 (Native Events) #
原生事件是浏览器原生提供的事件系统,直接绑定到 DOM 元素上。它们没有经过 React 的处理和优化,事件处理器直接响应浏览器的事件。
特点: #
- 直接绑定:原生事件处理器直接绑定到 DOM 元素上。
- 同步更新:在原生事件中,
setState
调用是同步的,每次状态更新都会立即触发重新渲染。 - 无统一接口:原生事件的接口和行为可能在不同浏览器中有所不同。
常见原生事件: #
- 使用
addEventListener
绑定的所有事件,如:click
,dblclick
,mousedown
,mouseup
,mousemove
,mouseenter
,mouseleave
,change
,input
,submit
,focus
,blur
,keydown
,keypress
,keyup
,touchstart
,touchmove
,touchend
,scroll
,drag
,dragstart
,dragend
,dragover
,dragenter
,dragleave
示例代码 #
合成事件: #
import React, { useState } from 'react';
function Example() {
const [count, setCount] = useState(0);
const handleClick = () => {
setCount(count + 1);
console.log('Synthetic event count:', count);
};
return (
<button onClick={handleClick}>Click me</button>
);
}
export default Example;
import React, { useState } from 'react';
function Example() {
const [count, setCount] = useState(0);
const handleClick = () => {
setCount(count + 1);
console.log('Synthetic event count:', count);
};
return (
<button onClick={handleClick}>Click me</button>
);
}
export default Example;
原生事件: #
import React, { useEffect, useState } from 'react';
function Example() {
const [count, setCount] = useState(0);
useEffect(() => {
const handleClick = () => {
setCount(count + 1);
console.log('Native event count:', count);
};
document.getElementById('nativeButton').addEventListener('click', handleClick);
return () => {
document.getElementById('nativeButton').removeEventListener('click', handleClick);
};
}, [count]);
return (
<button id="nativeButton">Click me</button>
);
}
export default Example;
import React, { useEffect, useState } from 'react';
function Example() {
const [count, setCount] = useState(0);
useEffect(() => {
const handleClick = () => {
setCount(count + 1);
console.log('Native event count:', count);
};
document.getElementById('nativeButton').addEventListener('click', handleClick);
return () => {
document.getElementById('nativeButton').removeEventListener('click', handleClick);
};
}, [count]);
return (
<button id="nativeButton">Click me</button>
);
}
export default Example;
在这个例子中:
- 合成事件中,
setState
是异步的,所以console.log
会输出旧的count
值。 - 原生事件中,
setState
是同步的,所以console.log
会立即反映最新的count
值。
版权属于: vincent
转载时须注明出处及本声明