响应事件
如何让交互触发事件处理器?
- 处理器: 传给
onClick等事件 prop 的函数,由 React 在事件发生时调用;写onClick={handleClick},不要在渲染时执行它; - 内联函数: 需要传参数时可写
onClick={() => save(id)},箭头函数延迟执行 save; - 语义元素: 可点击操作优先使用 button,使键盘、焦点与无障碍行为符合预期;
function SaveButton({ id, onSave }) {
return <button onClick={() => onSave(id)}>保存</button>;
}
如何给业务组件设计事件接口?
- 业务命名: 自定义组件可接收
onPlayMovie等表达业务意图的 prop,再在内部转接到原生事件; - 数据读取: 处理器可读取本次渲染的 props 和 state,快照含义见 state 快照笔记;
- 回调链: 子组件可以先处理本地操作,再显式调用父回调;这种方式能清楚展示执行顺序;
如何控制事件的向上传播?
- 冒泡: 多数 React 事件从目标向祖先传播,子按钮和外层容器的点击处理器都可能执行;
- 阻止传播: 子处理器调用
event.stopPropagation(),阻止该事件继续传播;onScroll是不冒泡的例外; - 捕获:
onClickCapture在目标处理和冒泡之前运行,适合记录捕获阶段的事件,不等于阻止默认行为;
function Toolbar() {
return (
<div onClick={() => console.log("工具栏")}>
<button
onClick={(event) => {
event.stopPropagation();
console.log("按钮");
}}
>
执行
</button>
</div>
);
}
如何阻止浏览器默认动作?
- 默认动作: 表单提交可能导航,链接点击可能跳转;需要接管这些行为时调用
event.preventDefault(); - 区别: 阻止默认动作不会自动阻止冒泡,二者解决不同问题;
- 副作用位置: 处理器可以提交请求、修改状态或弹出提示,不需要像渲染函数一样保持纯粹;
function Form() {
return (
<form
onSubmit={(event) => {
event.preventDefault();
console.log("在这里执行提交逻辑");
}}
>
<button>提交</button>
</form>
);
}