React的历史与应用
应用场景
- 前端应用开发
- 移动原生应用开发
- 结合Electron,进行桌面应用开发
发展历史
React的早期原型被称为“FaxJS”,它是由Facebook工程师Jordan Walke开发,因为他深受XHP的影响,XHP是一个简单的PHP HTML组件框架。React于2011年首次亮相,首次用于Facebook的Newsfeed。第二年在Instagram中使用。2013年5月,React在美国JSConf开源。
发展历程
React项目本身也越滚越大,从最早的UI引擎变成了一整套前后端通吃的Web App解决方案。衍生的React Native项目,希望用写Web App的方式去写Native App。如果能够实现,整个互联网行业都会被颠覆,因为同一组人只需要写一次UI ,就能同时运行在服务器、浏览器和手机。
React的设计思路
UI编程
if用JS来编程,会有以下弊端:
- 状态更新,UI不会自动更新,需要手动的调用DOM进行更新
- 欠缺基本的代码层面的封装和隔离,代码层面没有组件化
- UI之间的数据依赖关系,需要手动维护,如果依赖链路长,则会遇到“Callback Hell”
响应式与转换式
响应式系统
⭐事件 * →* 执行既定的回调 *** →*** 状态变更
前端UI
⭐事件 * →* 执行既定的回调 *** →*** 状态变更 → UI更新
React框架的期望
- 状态更新,UI自动更新
- 前端代码组件化,可复用,可封装
- 状态之间的互相依赖关系,只需声明即可
React组件化
- 组件是组件的组合/原子组件
- 组件内拥有状态,外部不可见
- 父组件可将状态传入组件内部
状态归属
“当前价格”——归属于root节点中
状态具有局部性
如果想让两个状态共享,那么这个状态就应该归属于两个节点向上寻找到最近的祖宗节点
1.React是单向数据流还是双向数据流????
- React是单向数据流【永远都是父组件给子组件传东西】
2.如何解决状态不合理上升问题????
3.组件的状态改变后,如何更新DOM?????
组件设计
-
组件声明了状态和UI映射
-
组件有Props/State两种状态
-
“组件”可由其他组件拼装而成
组件内部拥有私有状态State
组件接受外部的props状态提供复用性
根据当前的state/props,返回一个UI
生命周期
React(hooks)的写法
什么是hooks?
Hooks是一个新的React特性提案,组件尽量写成纯函数,如果需要外部React特性(比如状态管理,生命周期),就用钩子把外部特性"钩"进来,通常函数名字都是以use开头。首次在v16.7.0-alpha版本中添加,在v16.8.0中正式发布
hooks挂载在Fiber结点上的memoizedState,filber结构如下:
FiberNode { // fiber结构
memoziedState, // 组件更新的依据
type, // 原生或react
key,
tag,
...
}
特点:
1、无需修改组件结构的情况下复用状态逻辑;
2、可将组件中相互关联的部分拆分成更小的函数,复杂组件将变得更容易理解;
3、每一个组件内的函数(包括事件处理函数,effects,定时器或者api调用等等)会捕获某次渲染中定义的props和state;
4、memo缓存组件 ,useMemo缓存值, useCallback缓存函数;
5、每次render都有自己的props、state和effects。(每一个组件内的函数,包括事件处理函数,effects,定时器或者api调用等等,会捕获某次渲染中定义的props和state);
6、更新状态的时候(如setCount(count + 1)),React会重新渲染组件, 每一次渲染都能拿到独立的count状态,这个状态值是函数中的一个常量;
7、没有了显性的生命周期,所有渲染后的执行方法都在useEffect里面统一管理;
8、函数式编程,不需要定义constructor、render、class;
9、某一个组件,方法需不需要渲染、重新执行完全取决于开发者,方便管理。
React的实现
problems
- JSX不符合JS标准语法
- 返回的JSX发生改变时,如何更新DOM
- state/props更新时,要重新出发render函数
Virtual DOM(虚拟DOM)
Virtual DOM是一种用于和真实DOM同步,而在JS内存中维护的一个对象,它具有和DOM类似的树状结构,并和DOM可以建立一一对应的关系
它赋予了React声明样式的API:您告诉react希望让UI是什么状态,react就确保DOM匹配该状态。这使您可以从属性操作、事件处理和手动DOM更新这些在构建应用程序时必要的操作中解放出来
how to Diff?
完美的最小Diff算法,需要O(n^3)的复杂度
牺牲理论最小Diff,换取时间,得到了O(n)复杂度的算法:
Heyristic O(n) Algorithm
React状态管理库
核心思想:
将状态抽离到UI外部进行统一管理
状态机
当前状态,收到外部事件,迁移到下一个状态