React历史与应用
在使用React之前需要具备扎实的前端三件套HTML CSS javascript的知识;
历史背景
2010年,FaceBook在其php生态中引入了xhp框架,首次引入了组合式组件的思想,启发了后来的React设计
2011年:Jordan Walke 创造了FaxJS,也就是后来React原型
2012年:在FaceBook后沟Instagram后,该FaxJS项目在内部的到使用,Jordan Walke 基于FaxJS的经验,创造了React;
2013年:React正式开源,
2014----到今天。生态大爆发,
应用场景
- 前端用用开发;FaceBook,Instgram
- 移动原生应用开发,如Instagram,Discord
- 结合Electron,进行桌面端开发
甚至可以开发AR VR
React设计思路
原生UI编程痛点
- 状态更新UI不会自动更新,需要手动调用DOM及逆行更新
- 欠缺基本的代码层面的封装和隔离,代码层面没有组件
- UI之间的数据依赖关系,需要手动维护,如果依赖链路长,则会遇到Callback Hell
响应式与转换式
- 状态更新,UI自动更新
- 前端代码组件化,可封装。
- 状态之间的互相依赖关系,只需声明即可
组件化
像一个购物页面,可以简单分为三个组件,当然可以更细,一个按钮也可以是一个组件
- 组件是组合的组件/原子组件
- 组件内拥有状态,外部不可见
- 父组件可将状态传入组件内部
状态一般都具有局部性,
组件设计:
- 组件声明了状态和UI的映射
- 组件有Props,State两种状态, props是外部传入的参数,State是自己自身的数据
- 组件可由其他组件拼装而成
思考:
- React是单向数据流还是双向数据流?
单向数据流,
-
如何解决状态不合理的上升问题 ?
-
组件的状态改变后,如何更新DOM ?
组件的生命周期
React Hooks的写法
useState
import React, { memo, useState } from "react";
import { FC, ReactNode } from "react";
interface Props {
children?: ReactNode;
}
const App: FC<Props> = () => {
const [counter, setcounter] = useState<number>(0);
return (
<div>
<h1>{counter}</h1>
<button onClick={() => setcounter(counter + 1)}>点击改变状态</button>
</div>
);
};
export default memo(App);
useEffect 两个参数,一个参数是回调函数,第二个参数是,依赖的状态,如果第二个参数为空,则每次状态更新都会执行回调函数,且执行时机是在DOM更新完成之后执行
import React, { memo, useEffect, useState } from "react";
import { FC, ReactNode } from "react";
interface Props {
children?: ReactNode;
}
const App: FC<Props> = () => {
const [counter, setcounter] = useState<number>(0);
useEffect(() => {
document.title = counter + "标题";
});
return (
<div>
<h1>{counter}</h1>
<button onClick={() => setcounter(counter + 1)}>点击改变状态</button>
</div>
);
};
export default memo(App);
其他Hooks 基本都是基于这两个Hooks封装的
HOOKS 使用原则
不要在循环。条件或者嵌套函数中调用Hooks
React的实现
- JSX不符合JS标准语法
3. 返回的JSX,发生改变如何更新DOM
Diff 算法,虚拟DOM。
Virtual DOM 是一种用于和真实DOM同步的,而在JS内存中,维护一个对象,它具有和DOM类似的树状结构,并且可以和DOM建立联系一一对应的关系
当状态发生改变时,通过Diff算法,对比新旧虚拟DOM树,只更新改变的元素,未改变的元素,不进行更新操作
| Diff | |
|---|---|
| 不同类型的元素 | 替换 |
| 同类型的元素 | 更新 |
| 同类型的组件 | 递归 |
- State/props 更新时,要重新触发render函数
React状态管理库
组件间传递数据。当两个需要传递数据的组件相距好几个层级的时候,需要一级一级Props进行传递,这样是很麻烦的
状态管理库
将状态抽离到外部进行统一管理,可以直接进行全局状态共享,但是这样也是有缺点的,依赖全局store,造成无法拆分出来
什么时候使用这个状态管理库
主要分析一下,这个状态是被整个APP所拥有的,还有被某个组件所有拥有的,如果是被整个APP所拥有的,那么放在全局状态管理库中,是最好的选择,