掌握事件处理,让应用”动”起来
事件处理基础
基本语法
function App() {
const handleClick = () => {
alert('点击了按钮!');
};
return (
<button onClick={handleClick}>
点击我
</button>
);
}
传递参数
function App() {
const handleClick = (message) => {
alert(message);
};
return (
<button onClick={() => handleClick('Hello!')}>
点击我
</button>
);
}
使用事件对象
function App() {
const handleChange = (event) => {
console.log('输入值:', event.target.value);
console.log('事件类型:', event.type);
};
return (
<input onChange={handleChange} />
);
}
常见事件类型
表单事件
function Form() {
const handleSubmit = (e) => {
e.preventDefault(); // 阻止表单默认提交
console.log('表单提交');
};
const handleFocus = (e) => {
console.log('获得焦点');
};
const handleBlur = (e) => {
console.log('失去焦点');
};
return (
<form onSubmit={handleSubmit}>
<input
onFocus={handleFocus}
onBlur={handleBlur}
/>
<button type="submit">提交</button>
</form>
);
}
鼠标事件
function MouseDemo() {
const handleMouseEnter = (e) => {
console.log('鼠标进入');
};
const handleMouseLeave = (e) => {
console.log('鼠标离开');
};
const handleMouseMove = (e) => {
console.log(`位置: ${e.clientX}, ${e.clientY}`);
};
return (
<div
onMouseEnter={handleMouseEnter}
onMouseLeave={handleMouseLeave}
onMouseMove={handleMouseMove}
style={{ padding: 20, background: '#f0f0f0' }}
>
鼠标事件区域
</div>
);
}
键盘事件
function KeyboardDemo() {
const handleKeyDown = (e) => {
console.log('按键:', e.key);
console.log('按键码:', e.code);
// 常见用法
if (e.key === 'Enter') {
console.log('按下回车键');
}
if (e.ctrlKey && e.key === 's') {
e.preventDefault();
console.log('Ctrl+S 保存');
}
};
return (
<input
onKeyDown={handleKeyDown}
placeholder="输入一些文字..."
/>
);
}
受控组件
表单元素的 value 由 React state 控制的组件称为”受控组件”。
输入框
function InputDemo() {
const [value, setValue] = useState('');
return (
<input
value={value}
onChange={(e) => setValue(e.target.value)}
/>
);
}
文本域
function TextareaDemo() {
const [content, setContent] = useState('');
return (
<textarea
value={content}
onChange={(e) => setContent(e.target.value)}
rows={4}
/>
);
}
下拉选择
function SelectDemo() {
const [framework, setFramework] = useState('react');
return (
<select
value={framework}
onChange={(e) => setFramework(e.target.value)}
>
<option value="react">React</option>
<option value="vue">Vue</option>
<option value="angular">Angular</option>
</select>
);
}
复选框
function CheckboxDemo() {
const [isAgreed, setIsAgreed] = useState(false);
return (
<label>
<input
type="checkbox"
checked={isAgreed}
onChange={(e) => setIsAgreed(e.target.checked)}
/>
我同意条款
</label>
);
}
单选按钮
function RadioDemo() {
const [gender, setGender] = useState('male');
return (
<div>
<label>
<input
type="radio"
name="gender"
value="male"
checked={gender === 'male'}
onChange={(e) => setGender(e.target.value)}
/>
男
</label>
<label>
<input
type="radio"
name="gender"
value="female"
checked={gender === 'female'}
onChange={(e) => setGender(e.target.value)}
/>
女
</label>
</div>
);
}
表单综合示例
function RegistrationForm() {
const [formData, setFormData] = useState({
username: '',
email: '',
password: '',
gender: 'male',
agree: false
});
const handleChange = (e) => {
const { name, value, type, checked } = e.target;
setFormData(prev => ({
...prev,
[name]: type === 'checkbox' ? checked : value
}));
};
const handleSubmit = (e) => {
e.preventDefault();
console.log('提交数据:', formData);
};
return (
<form onSubmit={handleSubmit}>
<div>
<label>用户名:</label>
<input
type="text"
name="username"
value={formData.username}
onChange={handleChange}
/>
</div>
<div>
<label>邮箱:</label>
<input
type="email"
name="email"
value={formData.email}
onChange={handleChange}
/>
</div>
<div>
<label>密码:</label>
<input
type="password"
name="password"
value={formData.password}
onChange={handleChange}
/>
</div>
<div>
<label>性别:</label>
<select name="gender" value={formData.gender} onChange={handleChange}>
<option value="male">男</option>
<option value="female">女</option>
</select>
</div>
<div>
<label>
<input
type="checkbox"
name="agree"
checked={formData.agree}
onChange={handleChange}
/>
我同意服务条款
</label>
</div>
<button type="submit">注册</button>
</form>
);
}
非受控组件
表单元素的 value 由 DOM 本身控制的组件称为”非受控组件”。
function UncontrolledInput() {
const inputRef = useRef(null);
const handleSubmit = () => {
alert('输入的值: ' + inputRef.current.value);
};
return (
<div>
<input ref={inputRef} type="text" />
<button onClick={handleSubmit}>获取值</button>
</div>
);
}
事件处理的最佳实践
1. 事件处理函数提取
// ❌ 内联写法(复杂逻辑时不推荐)
<button onClick={() => { setCount(count + 1); setTotal(total + count); }}>
// ✅ 提取为独立函数
const handleClick = () => {
setCount(count + 1);
setTotal(total + count);
};
<button onClick={handleClick}>
2. 使用 useCallback 优化
import { useCallback } from 'react';
function App() {
const handleClick = useCallback(() => {
console.log('点击');
}, []); // 依赖数组为空,函数不会改变
return <button onClick={handleClick}>点击</button>;
}
3. 避免频繁创建函数
function List({ items, onItemClick }) {
return (
<ul>
{items.map(item => (
<li
key={item.id}
// ❌ 每次渲染都会创建新函数
onClick={() => onItemClick(item.id)}
>
{item.name}
</li>
))}
</ul>
);
}
总结
本章我们学习了:
- React 事件处理的基本语法
- 常见事件类型(表单、鼠标、键盘)
- 受控组件与非受控组件
- 表单处理的最佳实践
- 事件处理的性能优化
下一章我们将学习条件渲染与列表渲染。