====== 第七章:事件处理 ====== ===== 7.1 React 事件系统 ===== React 实现了一个合成事件系统(SyntheticEvent),它是浏览器原生事件的跨浏览器包装器。 **与原生事件的区别**: * 命名使用 camelCase:onClick 而非 onclick * 使用 JSX 表达式传入函数:onClick={handleClick} 而非 onClick="handleClick()" * 不能通过 return false 阻止默认行为,必须显式调用 preventDefault **示例**: // HTML // React **阻止默认行为**: // HTML 链接 // React function ActionLink() { function handleClick(e) { e.preventDefault(); console.log('链接被点击'); } return ( 点击我 ); } ===== 7.2 类组件中的事件绑定 ===== **绑定 this 的方法**: class Toggle extends React.Component { constructor(props) { super(props); this.state = { isToggleOn: true }; // 方法 1:在构造函数中绑定 this.handleClick = this.handleClick.bind(this); } handleClick() { this.setState(prevState => ({ isToggleOn: !prevState.isToggleOn })); } render() { return ( ); } } **其他绑定方法**: class Toggle extends React.Component { state = { isToggleOn: true }; // 方法 2:使用类属性语法(推荐) handleClick = () => { this.setState(prevState => ({ isToggleOn: !prevState.isToggleOn })); }; // 方法 3:在 render 中使用箭头函数(不推荐,每次渲染都创建新函数) render() { return ( ); } } ===== 7.3 向事件处理函数传递参数 ===== class List extends React.Component { handleClick = (id, event) => { console.log('ID:', id); console.log('Event:', event); }; render() { return ( ); } } ===== 7.4 常用事件 ===== **鼠标事件**: function MouseEvents() { const handleClick = () => console.log('点击'); const handleDoubleClick = () => console.log('双击'); const handleMouseEnter = () => console.log('鼠标进入'); const handleMouseLeave = () => console.log('鼠标离开'); const handleMouseMove = (e) => console.log('移动:', e.clientX, e.clientY); const handleContextMenu = (e) => { e.preventDefault(); console.log('右键菜单'); }; return (
鼠标事件区域
); }
**键盘事件**: function KeyboardEvents() { const handleKeyDown = (e) => { console.log('按下:', e.key, '键码:', e.keyCode); if (e.key === 'Enter') { console.log('回车键'); } if (e.ctrlKey && e.key === 's') { e.preventDefault(); console.log('Ctrl+S'); } }; const handleKeyUp = (e) => { console.log('释放:', e.key); }; return ( ); } **表单事件**: function FormEvents() { const handleChange = (e) => { console.log('值变化:', e.target.value); }; const handleFocus = () => console.log('获得焦点'); const handleBlur = () => console.log('失去焦点'); const handleInput = (e) => console.log('输入:', e.target.value); return ( ); } **焦点事件**: function FocusEvents() { const handleFocus = (e) => { console.log('焦点在:', e.target.name); }; const handleBlur = (e) => { console.log('离开:', e.target.name); }; return (
); }
===== 7.5 事件对象 ===== React 的合成事件对象(SyntheticEvent)是对原生事件的跨浏览器包装。 **常用属性**: * boolean bubbles * boolean cancelable * DOMEventTarget currentTarget * boolean defaultPrevented * number eventPhase * boolean isTrusted * DOMEventTarget target * number timeStamp * string type **常用方法**: * preventDefault() - 阻止默认行为 * stopPropagation() - 阻止事件冒泡 * persist() - React 17+ 已不需要,事件对象现在是持久的 function EventDemo() { const handleClick = (e) => { console.log('事件类型:', e.type); console.log('目标元素:', e.target); console.log('当前元素:', e.currentTarget); console.log('时间戳:', e.timeStamp); e.preventDefault(); // 阻止默认行为 e.stopPropagation(); // 阻止冒泡 }; return 点击; } ===== 7.6 事件委托 ===== React 使用事件委托机制,所有事件都被委托到 document 或应用根容器(React 17+)。 **优点**: * 减少内存消耗(不需要为每个元素绑定事件) * 动态添加的元素自动有事件处理 **注意**: * 事件处理函数中的 event.target 是实际触发事件的元素 * event.currentTarget 是绑定事件处理函数的元素 ===== 7.7 表单处理 ===== **受控组件**: function NameForm() { const [value, setValue] = useState(''); const handleChange = (e) => { setValue(e.target.value); }; const handleSubmit = (e) => { e.preventDefault(); alert('提交的名字: ' + value); }; return (
); }
**textarea**: // HTML 中 textarea 的值通过子元素设置 // React 中通过 value 属性设置 function EssayForm() { const [value, setValue] = useState('请撰写关于你喜欢的事物的文章'); return (