函数式编程
一种编程范式
- 纯函数
- 不可变值
vdom 和 diff 算法
- h 函数
- vnode 数据结构
- patch 函数
diff 算法(和 vue 的核心概念和实现思路一致)
- 只比较同一层级,不跨级比较
- tag 不相同,则直接删掉重建,不再深度比较
- tag 和 key,两者都相同,则认为是相同节点,不再深度比较
vue2 和 vue3 和 react 实现 vdom 的细节不一样 核心概念和实现思路一致
JSX 本质(编译出来的是什么)
等同于 vue 的模板
vue 的模板不是 html
jsx 不是 js
const ele = <div className="d" id="id1"><p>some p</p><p style={{fontSize: "20px", width: "200px", height: "200px"}}>设置 style</p><p>some p</p><input onClick={(event)=> console.log(event)} /><img src={imgSrc} />{/* 组件 */}<CustomComponent submit={onSubmit} /><ul>{this.state.list.map((item,index) => <li key={item.id}>index: {index} - title: {item.title}</li>)}</ul></div>// jsx ===> 转化为 vnodeconst ele = /*#__PURE__*/React.createElement("div", {className: "d",id: "id1"}, /*#__PURE__*/React.createElement("p", null, "some p"), /*#__PURE__*/React.createElement("p", {style: {fontSize: "20px",width: "200px",height: "200px"}}, "\u8BBE\u7F6E style"), /*#__PURE__*/React.createElement("p", null, "some p"), /*#__PURE__*/React.createElement("input", {onClick: event => console.log(event)}), /*#__PURE__*/React.createElement("img", {src: imgSrc}), /*#__PURE__*/React.createElement(CustomComponent, {submit: onSubmit}), /*#__PURE__*/React.createElement("ul", null, (void 0).state.list.map((item, index) => /*#__PURE__*/React.createElement("li", {key: item.id}, "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 事务机制
let transaction = {initialize: () => console.log("initialize"),close: () => console.log("close"),perform: (method) => method()}let method = () => console.log("method")transaction.initialize()transaction.perform(method)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 浏览器不支持
