React源码问题

React源码问题

  1. 请问为什么在早期版本中合成事件没有委托在 div#root 容器上?

  2. 给 react 里面 jsx 绑定的事件最终会缓存在什么地方?

  3. 合成事件的事件流机制React是如何通过 fiber 实现的?

  4. 当浏览器原生事件和React jsx 中的事件混在一起使用时,为什么React事件冒泡阶段早于浏览器原生的冒泡阶段?

  5. React.useReducer  函数使用的时候会返回一个数组,其中第一个是一个状态、第二个是一个函数,当更新的时候 React.useReducer 返回更新后的新状态,请问是如何缓存下来的?


正在回答 回答被采纳积分+1

登陆购买课程后可参与讨论,去登陆

1回答
Brian 2024-06-09 17:05:16

针对问题1:https://dev.to/grantcloyd/examining-react-s-synthetic-event-the-nativeevent-the-eventphase-and-bubbling-549k

这里的有一个文章你可以看看。

https://img1.sycdn.imooc.com/climg/666568e609f1267c08230705.jpg

早期的版本有很大的浏览器的兼容性的问题


针对问题2:应该是存在了event对象中


针对问题3:合成事件与FIber架构 是两个概念,而且关于合成事件的工作原理 这个问题非常大,请具象一点。


针对问题4:你这个问题的结论哪里来的?

React 所有事件都挂载在 document 对象上; 当真实 DOM 元素触发事件,会冒泡到 document 对象后,再处理 React 事件。


参考:https://juejin.cn/post/7068649069610024974


针对问题5:这里要来看看useReducer的源码了,基本原理是:React 通过保存一个指向当前 Hook 状态条目的指针来跟踪每个 Hook 调用



  • 提问者 慕粉3946981 #1
    1. 其实保存在文档或者说全局上不合理,保存到react挂载的容器DOM合理些。个人感觉

    2. 应该不是在事件里面首先原生事件对象是一个动态的实时的对象。比如说有一个嵌套的jsx里面有多个 onClick 和 onClickCapture 。react只会在容器上有一个点击事件,那些jsx上的事件处理函数保存在fiber.memoizedProps 属性里面,当在容器上触发点击事件的时候是基于原生事件对象取到事件目标,然后从事件目标中获取 fiber ,从这个里面取的。这个里面的调用栈有20多个,来模拟浏览器的事件流机制,把捕获或冒泡阶段的事件处理函数都依次收集然后依次触发执行

    3. 同2

    4. 这的确是个错误的问题

    5. 其实这个 useReducer 源码涉及的很巧妙,在jsx初始化的时候和更新的时候 useReducer 函数就不是同一个,切换机制是通过即将渲染的函数式FIber的alternate 获取页面正在使用的函数式Fiber从里面拿到Hook单向连接中第一个 + 初始状态,基于第1个Hook生成一个对应的新Hook并将Hook的更新队列运行获取最终的状态保存越来,然后再依次处理第2个第3个hook直到全部处理完毕。



    2024-06-09 23:23:10
  • 提问者 慕粉3946981 #2

    hook是一个单向的链表,hook里面的更新队列是个循环的单向链表,始终指向最后一个 (这样有个好处是通过 next 可以直接拿到头,也可以直接拿到尾,如果指向头的话,那想获取到尾还要遍历一个未知的长度)

    2024-06-09 23:26:34
  • 提问者 慕粉3946981 #3

    关于事件处理函数绑定的位置其实一直以来源码都在变,但总体来说思想就是挂在DOM的一个自定义属性上,然后借助浏览器的事件流机制从上面提取。

    2024-06-09 23:31:34
问题已解决,确定采纳
还有疑问,暂不采纳

恭喜解决一个难题,获得1积分~

来为老师/同学的回答评分吧

0 星
前端高级工程师(大前端)
  • 参与学习       303    人
  • 解答问题       388    个

全新打造“技术成长&职业破局”双高体系,深度打通“全栈 + 全流程 +多端+ 提效+AI赋能”,递进式锤炼思维与高阶技能,高效实现能力跃迁,助力成为“驾驭全局,深广兼备,打通多端全栈”的高级工程师

了解课程
请稍等 ...
意见反馈 帮助中心 APP下载
官方微信

在线咨询

领取优惠

免费试听

领取大纲

扫描二维码,添加
你的专属老师