## react源码解析14.手写hooks
#### 视频课程(高效学习):[进入课程](https://xiaochen1024.com/series/60b1b600712e370039088e24/60b1b636712e370039088e25)
#### 课程目录:
[1.开篇介绍和面试题](https://xiaochen1024.com/courseware/60b1b2f6cf10a4003b634718/60b1b311cf10a4003b634719)
[2.react的设计理念](https://xiaochen1024.com/courseware/60b1b2f6cf10a4003b634718/60b1b31ccf10a4003b63471a)
[3.react源码架构](https://xiaochen1024.com/courseware/60b1b2f6cf10a4003b634718/60b1b328cf10a4003b63471b)
[4.源码目录结构和调试](https://xiaochen1024.com/courseware/60b1b2f6cf10a4003b634718/60b1b32ecf10a4003b63471c)
[5.jsx&核心api](https://xiaochen1024.com/courseware/60b1b2f6cf10a4003b634718/60b1b334cf10a4003b63471d)
[6.legacy和concurrent模式入口函数](https://xiaochen1024.com/courseware/60b1b2f6cf10a4003b634718/60b1b33acf10a4003b63471e)
[7.Fiber架构](https://xiaochen1024.com/courseware/60b1b2f6cf10a4003b634718/60b1b340cf10a4003b63471f)
[8.render阶段](https://xiaochen1024.com/courseware/60b1b2f6cf10a4003b634718/60b1b348cf10a4003b634720)
[9.diff算法](https://xiaochen1024.com/courseware/60b1b2f6cf10a4003b634718/60b1b354cf10a4003b634721)
[10.commit阶段](https://xiaochen1024.com/courseware/60b1b2f6cf10a4003b634718/60b1b360cf10a4003b634722)
[11.生命周期](https://xiaochen1024.com/courseware/60b1b2f6cf10a4003b634718/60b1b367cf10a4003b634723)
[12.状态更新流程](https://xiaochen1024.com/courseware/60b1b2f6cf10a4003b634718/60b1b36ecf10a4003b634724)
[13.hooks源码](https://xiaochen1024.com/courseware/60b1b2f6cf10a4003b634718/60b1b374cf10a4003b634725)
[14.手写hooks](https://xiaochen1024.com/courseware/60b1b2f6cf10a4003b634718/60b1b37acf10a4003b634726)
[15.scheduler&Lane](https://xiaochen1024.com/courseware/60b1b2f6cf10a4003b634718/60b1b556cf10a4003b634727)
[16.concurrent模式](https://xiaochen1024.com/courseware/60b1b2f6cf10a4003b634718/60b1b55ccf10a4003b634728)
[17.context](https://xiaochen1024.com/courseware/60b1b2f6cf10a4003b634718/60b1b564cf10a4003b634729)
[18事件系统](https://xiaochen1024.com/courseware/60b1b2f6cf10a4003b634718/60b1b56ccf10a4003b63472a)
[19.手写迷你版react](https://xiaochen1024.com/courseware/60b1b2f6cf10a4003b634718/60b1b57bcf10a4003b63472b)
[20.总结&第一章的面试题解答](https://xiaochen1024.com/courseware/60b1b2f6cf10a4003b634718/60b1b581cf10a4003b63472c)
[21.demo](https://xiaochen1024.com/courseware/60b1b2f6cf10a4003b634718/60b1b587cf10a4003b63472d)
最关键的是要理解hook队列和update队列的指针指向和updateQueue的更新计算,详细见视频讲解
```js
import React from "react";
import ReactDOM from "react-dom";
let workInProgressHook;//当前工作中的hook
let isMount = true;//是否时mount时
const fiber = {//fiber节点
memoizedState: null,//hook链表
stateNode: App//dom
};
const Dispatcher = (() => {//Dispatcher对象
function mountWorkInProgressHook() {//mount时调用
const hook = {//构建hook
queue: {//更新队列
pending: null//未执行的update队列
},
memoizedState: null,//当前state
next: null//下一个hook
};
if (!fiber.memoizedState) {
fiber.memoizedState = hook;//第一个hook的话直接赋值给fiber.memoizedState
} else {
workInProgressHook.next = hook;//不是第一个的话就加在上一个hook的后面,形成链表
}
workInProgressHook = hook;//记录当前工作的hook
return workInProgressHook;
}
function updateWorkInProgressHook() {//update时调用
let curHook = workInProgressHook;
workInProgressHook = workInProgressHook.next;//下一个hook
return curHook;
}
function useState(initialState) {
let hook;
if (isMount) {
hook = mountWorkInProgressHook();
hook.memoizedState = initialState;//初始状态
} else {
hook = updateWorkInProgressHook();
}
let baseState = hook.memoizedState;//初始状态
if (hook.queue.pending) {
let firstUpdate = hook.queue.pending.next;//第一个update
do {
const action = firstUpdate.action;
baseState = action(baseState);
firstUpdate = firstUpdate.next;//循环update链表
} while (firstUpdate !== hook.queue.pending);//通过update的action计算state
hook.queue.pending = null;//重置update链表
}
hook.memoizedState = baseState;//赋值新的state
return [baseState, dispatchAction.bind(null, hook.queue)];//useState的返回
}
return {
useState
};
})();
function dispatchAction(queue, action) {//触发更新
const update = {//构建update
action,
next: null
};
if (queue.pending === null) {
update.next = update;//update的环状链表
} else {
update.next = queue.pending.next;//新的update的next指向前一个update
queue.pending.next = update;//前一个update的next指向新的update
}
queue.pending = update;//更新queue.pending
isMount = false;//标志mount结束
workInProgressHook = fiber.memoizedState;//更新workInProgressHook
schedule();//调度更新
}
function App() {
let [count, setCount] = Dispatcher.useState(1);
let [age, setAge] = Dispatcher.useState(10);
return (
<>
Clicked {count} times
Age is {age}
);
}
function schedule() {
ReactDOM.render(
, document.querySelector("#root"));
}
schedule();
```