- 初阶:
- 是什么:class component 代码重,且复用主要依赖 hoc、mixin,粒度大,代码组织比较混乱等;引入 fc,能让你更简洁定义组件代码,引入 hook,能在 fc 中使用 state 及其它 react 特性
 - 优点:
- 更细粒度的逻辑复用,函数 vs 对象
 - 单纯从应用角度看,相对比较容易理解 —— 毕竟相当于抛弃了 class 组件的生命周期概念
 
 - 原理简述:hook 底层会将状态挂载到 fiber 节点,在下次更新时就可以拿到上次状态,从而实现有副作用效果的 hook 功能
 
 中阶:实现原理,关键流程
- renderWithHook:关键函数
- 根据 current 节点状态判断是否第一次运行,是的话走 mountState 函数
 - 不是第一次运行,走 updateState
 
 mountState:核心逻辑:
- 调用 
mountWorkInProgressHook函数,创建当前 hook 对象:- 如果是第一个 hook:
currentlyRenderingFiber$1.memoizedState = workInProgressHook = hook;,也就是挂载到 fiber 节点的 memoizedState 链表,作为链表的第一个节点!!! - 如果是后面的hook,则 
workInProgressHook = workInProgressHook.next = hook;,也就是挂载到 fiber 节点 memoizedState 链表的最后一个节点 - fiber.memoizedState 形成链表结构,按 hook 顺序存储每一个 hook 的状态,这很重要!!! ```javascript function mountWorkInProgressHook(): Hook { const hook: Hook = { memoizedState: null,
 
 - 如果是第一个 hook:
 
baseState: null, baseQueue: null, queue: null,
next: null, };
- 调用 
 
if (workInProgressHook === null) { // This is the first hook in the list currentlyRenderingFiber.memoizedState = workInProgressHook = hook; } else { // Append to the end of the list workInProgressHook = workInProgressHook.next = hook; } return workInProgressHook; } ```
- 绑定 `dispatchSetState` 参数,参数中包含 current 节点,也就形成了一个闭包
dispatchSetState:setState 函数- 执行 action,计算新 state 值,并将这些更新信息保存到 update 对象中
 - 调用 
enqueueUpdate函数将更新任务添加到 hook 更新队列最后 - 调用 
scheduleUpdateOnFiber调度更新任务,最终调用updateState函数 
updateState:底层调用updateWorkInProgressHook,这里关键逻辑就是按照调用顺序,在memoiedState中找到对应的 hook 记录 ```javascript export function xx(){ const [data, setData] = useState(null); const [age, setAge] = useState(10); }
- renderWithHook:关键函数
 
fiber.memoizedState === hook[data] hook[data].next === hook[age] ```
- 之后,`updateReducer` 中循环执行所有 update 任务,计算出最新 state 值- state 值保存到 hook.memoridState 变量,完成更新- react 会用最新的 state 值计算 vdom,实现状态更新
- 高阶:
- 为什么不能在循环、if 等语句中调用 hook?为了确保每次 render 都是按相同的顺序执行 hook
- 因为会导致 
memoiedState链表结构发生变化,mount 与 update 就对不上了,很容易出问题 
 - 因为会导致 
 - 与函数式编程理念冲突吗?我认为不
- 函数式 !== 纯函数,副作用基本上是不可避免的
 - 在 fp 中,副作用一般通过 functor 等方式实现,目标是将副作用控制在有限范围内
 
 - 与 Vue 相比:
- 共同点:都用于实现更细粒度逻辑复用;都能够实现有副作用的状态管理;
 - 区别:
- react 任意 state 变更 —— 无论实际有没有参与组件渲染,都会导致组件重新 render;vue 则有响应式加持,仅当 render 函数依赖的属性发生变更时才重新渲染
 - react 会重复执行,hook 也会重复执行,需要用 useCallback 等缓存函数;vue setup 只会执行一次,hook 也只会有一次,gc 压力较小,也不需要考虑函数缓存
 - react 的副作用通过把状态挂载到 fiber 节点上;vue 则是给数据加上响应式能力
 - vue 对调用顺序没什么要求;react 有严格要求
 - react hook 依赖需要手动声明;vue 不需要
 
 
 - 最佳实践:
- state 初始化函数 
useState(initFunc)只会执行一次,所以 state 值不应该依赖 props 等可变参数 - 绝对不要在 for 、if 语句中执行hook;尽量保持在 render 函数顶层作用域执行hook
 
 - state 初始化函数 
 
 - 为什么不能在循环、if 等语句中调用 hook?为了确保每次 render 都是按相同的顺序执行 hook
 
资料:

