显示页面讨论过去修订反向链接回到顶部 本页面只读。您可以查看源文件,但不能更改它。如果您觉得这是系统错误,请联系管理员。 ====== 第七章:事件处理 ====== ===== 7.1 React 事件系统 ===== React 实现了一个合成事件系统(SyntheticEvent),它是浏览器原生事件的跨浏览器包装器。 **与原生事件的区别**: * 命名使用 camelCase:onClick 而非 onclick * 使用 JSX 表达式传入函数:onClick={handleClick} 而非 onClick="handleClick()" * 不能通过 return false 阻止默认行为,必须显式调用 preventDefault **示例**: <code javascript> // HTML <button onclick="activateLasers()">激活激光</button> // React <button onClick={activateLasers}>激活激光</button> </code> **阻止默认行为**: <code javascript> // HTML <a href="#" onclick="console.log('点击'); return false;">链接</a> // React function ActionLink() { function handleClick(e) { e.preventDefault(); console.log('链接被点击'); } return ( <a href="https://example.com" onClick={handleClick}> 点击我 </a> ); } </code> ===== 7.2 类组件中的事件绑定 ===== **绑定 this 的方法**: <code javascript> 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 ( <button onClick={this.handleClick}> {this.state.isToggleOn ? 'ON' : 'OFF'} </button> ); } } </code> **其他绑定方法**: <code javascript> class Toggle extends React.Component { state = { isToggleOn: true }; // 方法 2:使用类属性语法(推荐) handleClick = () => { this.setState(prevState => ({ isToggleOn: !prevState.isToggleOn })); }; // 方法 3:在 render 中使用箭头函数(不推荐,每次渲染都创建新函数) render() { return ( <button onClick={() => this.handleClick()}> {this.state.isToggleOn ? 'ON' : 'OFF'} </button> ); } } </code> ===== 7.3 向事件处理函数传递参数 ===== <code javascript> class List extends React.Component { handleClick = (id, event) => { console.log('ID:', id); console.log('Event:', event); }; render() { return ( <ul> {this.props.items.map(item => ( // 方法 1:箭头函数 <li key={item.id} onClick={(e) => this.handleClick(item.id, e)}> {item.name} </li> // 方法 2:bind(事件对象会自动传递) <li key={item.id} onClick={this.handleClick.bind(this, item.id)}> {item.name} </li> ))} </ul> ); } } </code> ===== 7.4 常用事件 ===== **鼠标事件**: <code javascript> 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 ( <div onClick={handleClick} onDoubleClick={handleDoubleClick} onMouseEnter={handleMouseEnter} onMouseLeave={handleMouseLeave} onMouseMove={handleMouseMove} onContextMenu={handleContextMenu} > 鼠标事件区域 </div> ); } </code> **键盘事件**: <code javascript> 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 ( <input type="text" onKeyDown={handleKeyDown} onKeyUp={handleKeyUp} /> ); } </code> **表单事件**: <code javascript> 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 ( <input type="text" onChange={handleChange} onFocus={handleFocus} onBlur={handleBlur} onInput={handleInput} /> ); } </code> **焦点事件**: <code javascript> function FocusEvents() { const handleFocus = (e) => { console.log('焦点在:', e.target.name); }; const handleBlur = (e) => { console.log('离开:', e.target.name); }; return ( <form> <input name="username" onFocus={handleFocus} onBlur={handleBlur} /> <input name="password" onFocus={handleFocus} onBlur={handleBlur} /> </form> ); } </code> ===== 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+ 已不需要,事件对象现在是持久的 <code javascript> 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 <a href="/" onClick={handleClick}>点击</a>; } </code> ===== 7.6 事件委托 ===== React 使用事件委托机制,所有事件都被委托到 document 或应用根容器(React 17+)。 **优点**: * 减少内存消耗(不需要为每个元素绑定事件) * 动态添加的元素自动有事件处理 **注意**: * 事件处理函数中的 event.target 是实际触发事件的元素 * event.currentTarget 是绑定事件处理函数的元素 ===== 7.7 表单处理 ===== **受控组件**: <code javascript> function NameForm() { const [value, setValue] = useState(''); const handleChange = (e) => { setValue(e.target.value); }; const handleSubmit = (e) => { e.preventDefault(); alert('提交的名字: ' + value); }; return ( <form onSubmit={handleSubmit}> <label> 名字: <input type="text" value={value} onChange={handleChange} /> </label> <input type="submit" value="提交" /> </form> ); } </code> **textarea**: <code javascript> // HTML 中 textarea 的值通过子元素设置 // React 中通过 value 属性设置 function EssayForm() { const [value, setValue] = useState('请撰写关于你喜欢的事物的文章'); return ( <textarea value={value} onChange={(e) => setValue(e.target.value)} /> ); } </code> **select**: <code javascript> function FlavorForm() { const [value, setValue] = useState('coconut'); return ( <label> 选择你喜欢的风味: <select value={value} onChange={(e) => setValue(e.target.value)}> <option value="grapefruit">葡萄柚</option> <option value="lime">酸橙</option> <option value="coconut">椰子</option> <option value="mango">芒果</option> </select> </label> ); } </code> **处理多个输入**: <code javascript> function ReservationForm() { const [state, setState] = useState({ isGoing: true, numberOfGuests: 2 }); const handleChange = (e) => { const { name, type, checked, value } = e.target; setState({ ...state, [name]: type === 'checkbox' ? checked : value }); }; return ( <form> <label> 参与: <input name="isGoing" type="checkbox" checked={state.isGoing} onChange={handleChange} /> </label> <br /> <label> 来宾人数: <input name="numberOfGuests" type="number" value={state.numberOfGuests} onChange={handleChange} /> </label> </form> ); } </code> **非受控组件**: <code javascript> function NameForm() { const inputRef = useRef(null); const handleSubmit = (e) => { e.preventDefault(); alert('Name: ' + inputRef.current.value); }; return ( <form onSubmit={handleSubmit}> <input type="text" ref={inputRef} /> <button type="submit">提交</button> </form> ); } </code> ===== 7.8 事件性能优化 ===== **使用 useCallback 缓存事件处理函数**: <code javascript> import { useCallback } from 'react'; function Parent() { const [count, setCount] = useState(0); // 每次渲染都创建新函数 const handleClick1 = () => { setCount(c => c + 1); }; // 只在依赖变化时创建新函数 const handleClick2 = useCallback(() => { setCount(c => c + 1); }, []); return ( <div> <Child onClick={handleClick1} /> <Child onClick={handleClick2} /> </div> ); } </code> **避免在 render 中创建新函数**: <code javascript> // 不推荐 function List({ items }) { return ( <ul> {items.map(item => ( <Item key={item.id} onClick={() => handleClick(item.id)} // 每次渲染都创建新函数 /> ))} </ul> ); } // 推荐 function List({ items }) { return ( <ul> {items.map(item => ( <ItemContainer key={item.id} item={item} /> ))} </ul> ); } function ItemContainer({ item }) { const handleClick = useCallback(() => { // 处理点击 }, [item.id]); return <Item onClick={handleClick} />; } </code> ===== 7.9 总结 ===== 本章详细介绍了 React 的事件处理: * 合成事件系统 * 事件绑定和 this 处理 * 常用事件类型 * 表单处理(受控和非受控组件) * 事件委托机制 * 事件性能优化 事件处理是 React 开发的基础,掌握这些知识对于构建交互式应用至关重要。 登录 Detach Close 该主题尚不存在 您访问的页面并不存在。如果允许,您可以使用创建该页面按钮来创建它。 react/事件处理.txt 最后更改: 2026/03/13 15:51由 张叶安 登录