现代 React Web 开发实战
宋一玮
FreeWheel 中国研发中心前端架构师
16115 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 31 讲
现代 React Web 开发实战
15
15
1.0x
00:00/00:00
登录|注册

11|事件处理:React合成事件是什么?为什么不用原生DOM事件?

你好,我是宋一玮,欢迎回到 React 应用开发的学习。
前面两节课我们学习了 React Hooks,加上前面第 8 节课学到的组件生命周期方法,这些 API 都可以用来编写组件逻辑。不过到目前为止,我们讲到的组件逻辑以展示为主,与用户的交互是偏单向的,而在实际项目中,Web 应用也包含很多双向交互。实现双向交互的一个重要途径,就是事件处理
在浏览器中,事件处理不是一个新鲜的概念。标准的 DOM API 中,有完整的 DOM 事件体系。利用 DOM 事件,尤其是其捕获和冒泡机制,网页可以实现很多复杂交互。
React 里内建了一套名为合成事件(SyntheticEvent)的事件系统,和 DOM 事件有所区别。不过第一次接触到合成事件概念的开发者,常会有以下疑问:
什么是 React 合成事件?
为什么要用合成事件而不直接用原生 DOM 事件?
合成事件有哪些使用场景?
有哪些场景下需要使用原生 DOM 事件?
经过这节课的学习,你将了解到合成事件的底层仍然是 DOM 事件,但隐藏了很多复杂性和跨浏览器时的不一致性,更易于在 React 框架中使用。在 oh-my-kanban 出现过的受控组件,就是合成事件的重要使用场景之一。此外,我们还会利用其他合成事件为看板卡片加入拖拽功能,顺便了解一下合成事件的冒泡捕获机制。最后,我会介绍一些在 React 中使用原生 DOM 事件的场景。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

React合成事件是React框架内建的一套事件系统,用于处理用户交互。相比原生DOM事件,合成事件隐藏了复杂性和跨浏览器的不一致性,更易于在React框架中使用。React规范化了一些在各个浏览器间行为不一致的事件,如`onChange`、`onBeforeInput`、`onMouseEnter`等,使开发者不用再担心事件处理的浏览器兼容性问题。通过合成事件,开发者可以更方便地处理用户交互,同时享受React框架带来的便利。 另外,文章还介绍了受控组件和表单处理的重要性,以及如何利用React state和合成事件处理用户交互,形成闭环,从而实现受控组件。通过这种方式,开发者可以轻松获取表单数据并进行验证、提交到服务器端等操作。文章还提到了显式地将表单元素集中在一个`<form>`表单里,以及禁用表单提交事件的默认行为的方法。 此外,文章还涉及了合成事件的冒泡和捕获机制,以及在React应用中使用原生DOM事件的情况。总的来说,本文深入介绍了React合成事件和受控组件的基础知识,为读者提供了对React事件处理和表单交互的全面了解,为后续课程的学习打下了基础。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《现代 React Web 开发实战》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(11)

  • 最新
  • 精选
  • 🐑
    置顶
    你好,我是《现代React Web开发实战》的编辑辰洋,这是👇项目的源代码链接,供你学习与参考:https://gitee.com/evisong/geektime-column-oh-my-kanban/releases/tag/v0.11.0
    2022-09-19归属地:北京
  • 海华呀
    1、执行顺序 是父-子-父,有些洋葱圈模型的感觉 <div onClickCapture={() => console.log(1)} onClick={() =>console.log(4)} > <p onClickCapture={() => console.log(2)} onClick={() => { console.log(3) }}> target </p> </div > 例如这个点击会依次打印出1、2、3、4; 阻止冒泡 一般是父子组件都对事件做了处理,例如 文章列表页 ,点赞按钮,和打开详情页面;

    作者回复: 你好,海华呀,很简洁有效的实验,赞!

    2022-10-18归属地:北京
    2
  • WL
    感觉老师讲得过于多内容了,看着挺花时间;可以简化些就更好了

    作者回复: 你好,WL,感谢你的反馈。目前这个专栏的整体,还有每节课的局部,基本都是按照表层-底层-表层-底层逻辑设计的,每节课设计的内容密度与这套逻辑相关。我和专栏编辑也商量过,在不改变课程总体设计的前提下,我们会尽量平衡各位同学的学习需求。

    2022-09-15归属地:北京
    1
  • 潮汐
    老师,想问一下,这节课的拖拽的例子,你的拖拽开始的时候,卡片会不会有一闪而过的卡片时间从status的时间变成相对时间的画面。分析了下,感觉像是KanbanCard的setDraggedItem触发了App的更新渲染,KanbanColumn和KanbanCard也会被重新渲染。但是draggedItem也并没有传给KanbanCard,为啥会触发KanbanCard的协调更新呢。

    作者回复: 你好,潮汐,我用 https://gitee.com/evisong/geektime-column-oh-my-kanban/releases/tag/v0.11.0 的代码在本地跑了一下,没观察到你说的情况,请问你使用的 git commit id 和浏览器版本是怎样的?

    2023-01-08归属地:中国香港
    3
  • 阿阳
    每节课的内容好多,全是干货。需要反复的听,看,动手实践。请问老师,每节课的课后习题有没有专门的章节做解答啊?

    作者回复: 你好,阿阳,感谢你的认可,衷心希望你从本专栏中有所收获。 专栏每节课课后都有1~2个思考题,初衷是为了鼓励同学们思考、讨论,提升学习效果。可以看到在每节课的留言区,已经有了不少优秀的答案,一些答案下面有我的评论,也有部分答案引起了同学们的热烈讨论。 在连载期间,根据同学们的留言,我们也选了3个主题制作上线了两节加餐:《加餐01|留言区心愿单:真·子组件以及jsx-runtime》和《加餐02|留言区心愿单:Fiber协调引擎》。目前虽然连载已经告一段落,还是非常欢迎同学们留言参与互动,我们也会根据同学们的需求,考虑是否额外加餐。 在此也感谢所有参与互动的同学们,谢谢你们!

    2022-11-29归属地:北京
  • 癡癡的等你歸
    老师,课程源码不见了,404了

    作者回复: 你好,癡癡的等你歸,你说的源码链接是下面这个吗? https://gitee.com/evisong/geektime-column-oh-my-kanban/releases/tag/v0.11.0 我用电信宽带和联通5G都试了试,目前都能正常访问(虽然后者有点慢)。请再试试,如果还是不行请告诉我们你的电信提供商和连接方式,我会请Gitee排查。

    2022-11-16归属地:北京
  • Geek_8e9c8d
    已经开始期待以后开的项目课了 希望能得到省份和城市的那个思考题的更多提示~,谢谢

    作者回复: 你好,Geek_8e9c8d,抱歉由于之前一直在赶稿,这么久才回复。第24节课的特别企划开源项目在: https://gitee.com/evisong/geektime-column-oh-my-kit 很快就会正式运转起来,非常期待你的加入。 关于第10节课省份+城市的思考题,基本知识点就是那个依赖值数组。文稿中的代码: // ------------ -------------- // | 省份... |v| | 城市... |v| // ------------ -------------- const [province, setProvince] = useState(null); const [cities, setCities] = useState([]); useEffect(() => { if (province === '山东') { // 这些数据可以是本地数据,也可以现从服务器端读取 setCities(['济南', '青岛', '淄博']); } }, [province]); 意思就是当 province值有变化才会再次执行前面的副作用回调函数,来更新城市列表state。

    2022-10-10归属地:北京
  • 01
    对目前发展来讲, 合成事件是否是个好的选择。 同时是否增加了开发的心智负担。 许多类react相关库不采用合成事件代替原生事件。

    作者回复: 你好,01,这是个好问题。我也赞同合成事件增加了开发者的认知负担。不过我也会从下面几个方面思考合成事件对于React的必要性: 1. React对事件系统的限制。对于DOM event,只要开发者愿意,可以做到很多替代React数据流的事情,而合成事件,则只保留了主要是与用户交互相关的部分能力,保证它不会跟React其他特性抢活儿。 2. 合成事件对于特定事件的所谓规范化,尤其是onChange,算是受控组件的基本实现原理,如果放手给原生DOM事件,受控组件方案可能需要调整。 3. 原生DOM event的事件处理是同步执行的,可能会阻塞页面,我本想对比一下合成事件处理是不是异步执行的,但我查过React源码packages/react-dom/src/events/和一些资料,还没有发现有地方说明这一点。 4. 在React 17,合成事件处理函数中修改多次state,会自动批处理,只触发一次渲染,原生DOM事件处理函数中如果也修改多个state,是不享受这个待遇的;不过这个优势在React 18已经不存在了,只要是事件处理函数中,都可以自动批处理,只渲染一次: elm.addEventListener('click', () => { setCount(c => c + 1); setFlag(f => !f); // React will only re-render once at the end (that's batching!) }); 具体可以参考 https://github.com/reactwg/react-18/discussions/21 如有补充或其他观点,欢迎继续回复讨论。

    2022-09-27归属地:北京
    2
  • joel
    终于追上来了

    作者回复: 你好,joel,我看了下你留言的日期,学习速度快得让人羡慕 :) 很高兴专栏能引起你的学习兴趣。

    2022-09-15归属地:北京
  • C0S_02
    老师您好,我一直没明白 合成事件 的必要性是什么,react 到底在解决什么需求
    2023-05-27归属地:四川
    1
收起评论
显示
设置
留言
11
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部