React 事件处理与原生事件有什么不同?
先理解原理和示例,再练习完整口述与追问。
回答要点
理解事件对象、冒泡、默认行为和处理函数引用;阻止冒泡与阻止默认动作是不同操作。事件委托实现与版本有关,不要把旧版本的事件池结论套到现代 React DOM。
原理拆解
React 事件提供与组件树结合的统一事件接口,具体委托位置和事件差异受版本影响。event.target 指实际触发目标,currentTarget 指当前处理器绑定的元素;阻止默认行为与阻止传播是两件事。Portal 让 DOM 位置改变,但事件仍可沿 React 的逻辑组件树传播,因此不能仅看 DOM 父节点判断 React 父处理器是否收到事件。
示例与推演
按钮内有图标,点击图标时 target 是图标,currentTarget 仍是按钮。表单按钮默认可能提交表单,应声明正确 type;preventDefault 阻止默认提交,stopPropagation 则限制传播。Portal 弹窗的内部点击可能触发组件树外层的 onClick,关闭遮罩应按真实目标和业务规则处理。
易错点
不要笼统说所有 React 事件都与原生冒泡完全一致。React17 起常见事件池规则改变,不能对现代 Web 项目继续无条件要求 event.persist。
参考回答可直接练习口述
React DOM 提供统一的事件处理接口,处理函数接收事件对象,冒泡和默认动作仍要分别理解。stopPropagation 阻止传播,preventDefault 阻止默认动作。React17 起常见事件委托位置从 document 改到 root 容器,现代 Web React 也不再采用旧式事件对象池,不能照搬旧版本结论。
面试官可能继续问追问与完整解答展开收起
追问
onClick={fn} 与 onClick={fn()} 有何差异?Portal 中的事件沿实际 DOM 还是 React 逻辑树传播?
追问回答
onClick={fn} 是传处理函数,onClick={fn()} 是渲染时立即调用并把返回值传给属性。Portal 改变 DOM 挂载位置,但 React 事件通常沿 React 逻辑树传播;原生 addEventListener 的传播遵循实际 DOM 路径,应区分两套视角。