这是我参与「第四届青训营 」笔记创作活动的的第14天
零. 前置知识
- HTML、JS、CSS基础
- 数据结构基础知识,如二叉树、深度遍历。
- 熟悉浏览器提供的DOM API,了解如何使用API修改DOM、更新UI。
一. React的历史与应用
应用:
- 前端应用开发
- 移动原生应用开发
- 桌面应用开发
历史:
- 2010年,Facebook在其php生态中,引入了xhp框架,首次引入了组合式组件的思想,启发了后来的React 的设计。
- 2011年,Jordan Walke创造了FaxJS,也就是后来的React原型。
- 2012年,在Facebook收购Instagram后,该FaxJS项目在内部得到使用,Jordan Walke基于FaxJS的经验,实现了React。
- 2013年,React正式开源,在2013 JSConf 上 Jordan Walke介绍了这款全新的框架。
- 2014年至今,生态大爆发,各种围绕React 的新工具/新框架开始涌现。
二. React的设计思路
1. 举例
如图所示,当下方两块选项改变,右上角需要随之改变,按照传统思路,需要再两块选项的回调函数里 添加修改后触发的回调函数 修改右上角。
- 状态更新,UI不会自动更新,需要手动地调用DOM进行更新。
- 欠缺基本的代码层面的封装和隔离,代码层面没有组件化。
- UI之间的数据依赖关系,需要手动维护,如果依赖链路长,则会遇到“Callback Hell”(回调地狱)。
2. 响应式与转换式系统
转换式系统:给定[输入]求解[输出],例如 编译器、数值计算。
响应式系统:监听事件消息驱动,例如 实时监控系统、UI界面。
3. 响应式编程
- 状态更新,UI自动更新。
- 前端代码组件化,可复用,可封装。
- 状态之间的互相依赖关系,只需声明即可。
4. 组件化与状态归属
左侧不是DOM树,DOM是浏览器内部的东西。JS只能通过DOM的API获取变量,JS内部不含有DOM变量。
当两个组件需要共享状态的时候,将状态上移,但如果是这样的话,很多状态都会放到root节点,失去了我们组件隔离的意义。
- 组件是组建的组合\原子的组合
- 组件内拥有状态,外部不可见
- 父组件可将状态传入组件内部
5. 组件设计
- 组件声明了状态和UI的映射。
- 组件有Props/State两种状态。(内部私有状态state,外部传入的props)
- “组件"可由其他组件拼装而成。
6. 生命周期
- Mounting 挂载时
- Updating 更新时
- Unmounting 销毁时
三. React (hooks)的写法
useState :传入状态初始值。返回一个状态和设置该状态的函数,用户可以通过调用该函数实现状态的修改。
useEffect:副作用,需要用useEffect。有两个参数,一个是函数,一个是数组。当第二个参数省略的时候,第一个函数只会在mount挂载的时候执行一次。
hooks:挂载到react生命周期上执行的函数。例如useState(),useEffect()。
hooks使用原则:不要在判断条件或循环内使用hooks函数。
四. React的实现
1. 问题
- JSX 不符合 JS 标准语法
- 返回的 JSX 发生改变时,如何更新 DOM
- State/Props更新时,要重新触发 render 函数
2. 解决
- transpile
这个语法只是虚拟的,最终会进行转义,最后还是会转义成JavaScript语法。
- 虚拟DOM
使用 虚拟DOM树 虚拟DOM树和真实的DOM树会建立一一对应的关系,当虚拟DOM树发生改变时,React会确保真实的DOM也发生相应的改变。
- diff 算法
如果将全部的DOM删除,再将所有DOM重新绘制,非常耗时,我们需要一个算法去对比新旧版本中有修改的部分,只对更改的DOM做更新。diff算法本身不能太耗时,我们希望diff尽可能小计算时间尽可能短。
DIFF:tradeoff问题
完美的 diff 算法需要的时间复杂度为 O(n^3),而React牺牲了理论最小的 Diff,换取了时间,得到了 O(n)的时间复杂度。虚拟的DOM修改状态后,类型会发生改变。
- 若真实的DOM和虚拟的DOM不同的类型会替换,然后会将类型不同的虚拟DOM子节点全部替换;
- 若类型相同的DOM元素,进行更新;
- 若同类型的组件元素,进行递归。
五. React状态管理库
状态管理库是React的核心功能,它可以将数据保存到状态管理库中,这样就不用将组件内的状态的改变用函数的方式来改变了。但是并不是所有的组件都适合用这种方式保存状态,例如自己写的小组件,可以被别人使用,作为组件,不可能将数据都保存到状态管理库中,因该是封装度高的,所有数据都在组件内部的。还有有一些数据因该只是组件内可见的,如果到了状态管理库中,就将数据变得所有组件都可见了,这是不安全的。
将状态抽离到UI外部进行统一管理。
- store适合放置距离远的组件、需要所有组件共享的消息。
- 判断状态是被整个APP拥有的还是被一个组件拥有的。
- 登录用户的信息:用户名、用户头像等适合放到store。
react状态管理库:很大的状态机。不用纠结用哪个,用哪个都行。
状态机:当前状态,收到外部事件,迁移到下一个状态。
六. 应用级框架科普
- next.js
硅谷明星创业公司Vercel的 React开发框架,稳定,开发体验好,支持Unbundled Dev,sWC等,其同样有Serverless一键部署平台帮助开发者快速完成部署。口号是"Let's Make Web Faster”。
- modern.js
字节跳动Web Infra团队研发的全栈开发框架,内置了很多开箱即用的能力与最佳实践,可以减少很多调研选择工具的时间。
- blitz
无API思想的全栈开发框架,开发过程中无需写API调用与CRUD逻辑,适合前后端紧密结合的小团队项目。