跳到主要内容

事件处理

本章节将介绍 React 中的事件处理机制。

事件处理器

在 React 中,事件处理函数使用 camelCase 命名:

function MyButton() {
function handleClick() {
alert("按钮被点击了!");
}

return <button onClick={handleClick}>点击我</button>;
}

传递参数

使用箭头函数

function ActionButtons() {
const handleDelete = (id) => {
console.log("删除", id);
};

const handleEdit = (id) => {
console.log("编辑", id);
};

return (
<div>
<button onClick={() => handleDelete(1)}>删除</button>
<button onClick={() => handleEdit(1)}>编辑</button>
</div>
);
}

使用 bind 方法

function ActionButtons() {
function handleDelete(id) {
console.log("删除", id);
}

return (
<div>
<button onClick={handleDelete.bind(this, 1)}>删除</button>
</div>
);
}

获取事件对象

function InputExample() {
const handleChange = (event) => {
console.log(event.target.value); // 输入的值
console.log(event.target.name); // 输入框的 name
};

return (
<input
type="text"
name="username"
onChange={handleChange}
/>
);
}

表单事件

input 事件

function InputForm() {
const [value, setValue] = useState("");

return (
<form>
<input
type="text"
value={value}
onChange={(e) => setValue(e.target.value)}
/>
<p>输入的内容: {value}</p>
</form>
);
}

textarea

function TextAreaForm() {
const [content, setContent] = useState("");

return (
<form>
<textarea
value={content}
onChange={(e) => setContent(e.target.value)}
rows={5}
/>
<p>字数: {content.length}</p>
</form>
);
}

select

function SelectForm() {
const [city, setCity] = useState("beijing");

return (
<form>
<select
value={city}
onChange={(e) => setCity(e.target.value)}
>
<option value="beijing">北京</option>
<option value="shanghai">上海</option>
<option value="guangzhou">广州</option>
<option value="shenzhen">深圳</option>
</select>
<p>选择的城市: {city}</p>
</form>
);
}

表单提交

function LoginForm() {
const [username, setUsername] = useState("");
const [password, setPassword] = useState("");

const handleSubmit = (e) => {
e.preventDefault(); // 阻止表单默认提交
console.log("提交:", username, password);
// 发送登录请求
};

return (
<form onSubmit={handleSubmit}>
<div>
<label>用户名: </label>
<input
type="text"
value={username}
onChange={(e) => setUsername(e.target.value)}
/>
</div>
<div>
<label>密码: </label>
<input
type="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
/>
</div>
<button type="submit">登录</button>
</form>
);
}

常见的 HTML 事件

鼠标事件

function MouseEvents() {
const handleClick = () => console.log("点击");
const handleDoubleClick = () => console.log("双击");
const handleMouseEnter = () => console.log("鼠标进入");
const handleMouseLeave = () => console.log("鼠标离开");

return (
<div
onClick={handleClick}
onDoubleClick={handleDoubleClick}
onMouseEnter={handleMouseEnter}
onMouseLeave={handleMouseLeave}
style={{ padding: 20, background: "#f0f0f0" }}
>
鼠标事件示例
</div>
);
}

键盘事件

function KeyboardEvents() {
const handleKeyDown = (e) => {
console.log("按键:", e.key);
console.log("按键代码:", e.code);
};

const handleKeyPress = (e) => {
console.log("按键 pressed:", e.key);
};

const handleKeyUp = (e) => {
console.log("按键 up:", e.key);
};

return (
<input
type="text"
onKeyDown={handleKeyDown}
onKeyPress={handleKeyPress}
onKeyUp={handleKeyUp}
placeholder="输入文字"
/>
);
}

焦点事件

function FocusEvents() {
const handleFocus = () => console.log("获取焦点");
const handleBlur = () => console.log("失去焦点");

return (
<input
type="text"
onFocus={handleFocus}
onBlur={handleBlur}
placeholder="聚焦/失焦"
/>
);
}

剪切板事件

function ClipboardEvents() {
const handleCopy = (e) => {
console.log("复制事件");
// 可以阻止复制
// e.preventDefault();
};

const handleCut = (e) => {
console.log("剪切事件");
};

const handlePaste = (e) => {
console.log("粘贴事件");
// 获取粘贴的内容
const text = e.clipboardData.getData("text");
console.log("粘贴内容:", text);
};

return (
<textarea
onCopy={handleCopy}
onCut={handleCut}
onPaste={handlePaste}
placeholder="复制、剪切、粘贴"
/>
);
}

事件处理器中的 this

问题

class Button extends Component {
handleClick() {
console.log(this); // undefined
}

render() {
// 错误:this 未绑定
return <button onClick={this.handleClick}>点击</button>;
}
}

解决方案 1:使用箭头函数

class Button extends Component {
handleClick = () => {
console.log(this); // 正确指向组件实例
};

render() {
return <button onClick={this.handleClick}>点击</button>;
}
}

解决方案 2:在 constructor 中绑定

class Button extends Component {
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
}

handleClick() {
console.log(this);
}

render() {
return <button onClick={this.handleClick}>点击</button>;
}
}

函数组件中的事件处理

function Button() {
// 推荐:使用箭头函数
const handleClick = () => {
console.log("点击");
};

return <button onClick={handleClick}>点击</button>;
}

事件冒泡和阻止

function EventBubbling() {
const handleParentClick = () => {
console.log("父元素点击");
};

const handleChildClick = (e) => {
e.stopPropagation(); // 阻止事件冒泡
console.log("子元素点击");
};

return (
<div onClick={handleParentClick} style={{ padding: 20 }}>
父元素
<button onClick={handleChildClick}>子按钮</button>
</div>
);
}

小结

本章我们学习了:

  1. React 事件处理的基本写法
  2. 事件处理器中传递参数
  3. 获取事件对象
  4. 表单事件处理
  5. 常见的 HTML 事件
  6. this 绑定问题
  7. 事件冒泡和阻止

练习

  1. 创建一个登录表单,验证用户名和密码
  2. 创建一个搜索框,支持回车搜索
  3. 创建一个 todo list,支持回车添加
  4. 创建一个图片画廊,点击切换图片