函数式编程

一种编程范式

  • 纯函数
  • 不可变值

vdom 和 diff 算法

  • h 函数
  • vnode 数据结构
  • patch 函数

diff 算法(和 vue 的核心概念和实现思路一致)

  • 只比较同一层级,不跨级比较
  • tag 不相同,则直接删掉重建,不再深度比较
  • tag 和 key,两者都相同,则认为是相同节点,不再深度比较

vue2 和 vue3 和 react 实现 vdom 的细节不一样 核心概念和实现思路一致

JSX 本质(编译出来的是什么)

等同于 vue 的模板
vue 的模板不是 html
jsx 不是 js

  1. const ele = <div className="d" id="id1">
  2. <p>some p</p>
  3. <p style={{fontSize: "20px", width: "200px", height: "200px"}}>设置 style</p>
  4. <p>some p</p>
  5. <input onClick={(event)=> console.log(event)} />
  6. <img src={imgSrc} />
  7. {/* 组件 */}
  8. <CustomComponent submit={onSubmit} />
  9. <ul>
  10. {this.state.list.map((item,index) => <li key={item.id}>index: {index} - title: {item.title}</li>)}
  11. </ul>
  12. </div>
  13. // jsx ===> 转化为 vnode
  14. const ele = /*#__PURE__*/React.createElement("div", {
  15. className: "d",
  16. id: "id1"
  17. }, /*#__PURE__*/React.createElement("p", null, "some p"), /*#__PURE__*/React.createElement("p", {
  18. style: {
  19. fontSize: "20px",
  20. width: "200px",
  21. height: "200px"
  22. }
  23. }, "\u8BBE\u7F6E style"), /*#__PURE__*/React.createElement("p", null, "some p"), /*#__PURE__*/React.createElement("input", {
  24. onClick: event => console.log(event)
  25. }), /*#__PURE__*/React.createElement("img", {
  26. src: imgSrc
  27. }), /*#__PURE__*/React.createElement(CustomComponent, {
  28. submit: onSubmit
  29. }), /*#__PURE__*/React.createElement("ul", null, (void 0).state.list.map((item, index) => /*#__PURE__*/React.createElement("li", {
  30. key: item.id
  31. }, "index: ", index, " - title: ", item.title))));

jsx 中组件名首字母必须大写

合成事件

所有事件挂载到 document (仅仅在 React16 中)上,react17 绑定到 root 组件上,有利于多个 React 版本并存,例如微前端
event 不是原生的,是 SyntheticEvent 合成事件对象

更好的兼容性和跨平台 减少内存消耗,避免频繁解绑 方便事件的统一管理(事务机制)

setState 和 batchUpdate

setState:

  • 有时异步(普通使用),有时同步(setTimeout,自定义的 DOM 事件)
  • 有时合并(对象形式),有时不合并(函数形式)

setState 是异步还是同步?

  • setState 本身没有异步同步
  • 看是否命中 batchUpdate 机制
  • 判断 isBatchingUpdates

哪些能命中 batchUpdate 机制?

  • 生命周期(和它里面所调用的函数)
  • React 中注册的事件(和它里面所调用的函数)
  • React 可以 “ 管理 “ 的入口

哪些不能命中 batchUpdate 机制?

  • setTimeout,setInterval(和它里面所调用的函数)
  • 自定义 DOM 事件(和它里面所调用的函数)
  • React “ 管不到 “ 的入口

transaction 事务机制

  1. let transaction = {
  2. initialize: () => console.log("initialize"),
  3. close: () => console.log("close"),
  4. perform: (method) => method()
  5. }
  6. let method = () => console.log("method")
  7. transaction.initialize()
  8. transaction.perform(method)
  9. transaction.close()

组件渲染和更新过程

  • JSX 本质就是一个 createElement 函数
  • 执行生成 vnode
  • patch(elem, vnode) 和 patch(vnode, newVnode)

点击查看【processon】
组件渲染过程:

  • props state
  • render() 函数 生成 vnode
  • patch(elem, vnode)

组件更新过程:

  • setState(newState) —> dirtyComponents ( 可能有子组件 )
  • render() 生成 newVnode
  • patch(vnode, newVnode)

patch 在 react 中分为 2 个阶段:

  • reconciliation 阶段 - 执行 diff 算法,纯 JS 计算
  • commit 阶段 - 将 diff 算法结果渲染到 DOM

考虑到性能问题

React fiber

在 reconciliation 阶段进行拆分为多任务(commit 阶段 无法拆分)
DOM 需要渲染时暂停,空闲时恢复

window.requestIdleCallback

注意:safari 浏览器不支持

前端路由