核心思想
- 链表
- 环状链表
- 队列
- 顺序执行
/**
* 实现一个 react hooks的 useState
*/
let isMount = true;
let workInProgressHook = null; // 全局的链表 当前执行的 state
function App(){
const [num, updateNum] = useState(0);
const [num1, updateNum1] = useState(22);
const [num2, updateNum2] = useState(33);
console.log('isMount?', isMount);
console.log(`num: `, num);
return {
onClick: () => {
updateNum(x => x + 1);
updateNum1(y => y + 10);
}
}
}
const fiber = {
stateNode: App,
memoizedStates: null, // 链表 函数组件每一个hook;
};
function schedule(){
workInProgressHook = fiber.memoizedStates;
const app = fiber.stateNode();
isMount = false;
return app;
}
function useState(initialState){
let hook;
if(isMount){ // 首次渲染
hook = {
memoizedStates: initialState,
next: null,
queue: { // 环状链表队列
pending: null, // 下一个要执行的东西
},
}
if(!fiber.memoizedStates){
fiber.memoizedStates = hook; //第一个useState
} else {
workInProgressHook.next = hook; // 其余useState 将hook 赋值给 fibel.memoizedStates.next
}
workInProgressHook = hook; // 当前的hook
}
else { // 组件更新时 一样调用这里的方法 更新数据
hook = workInProgressHook;
workInProgressHook = workInProgressHook.next; // 获得下一个hook
}
let baseState = hook.memoizedStates;
if(hook.queue.pending){
let firstUpdate = hook.queue.pending.next;
do{
const action = firstUpdate.action;
baseState = action(baseState);
firstUpdate = firstUpdate.next;
} while( firstUpdate !== hook.queue.pending.next) // 遍历环状链表
hook.queue.pending = null;
}
hook.memoizedStates = baseState; // 新的state值
console.log(hook.queue);
return [baseState, dispathAction.bind(null, hook.queue)];
}
function dispathAction(queue, action){
const update = {
action,
next: null,
};
if (queue.pending === null) { // 环状链表
update.next = update;
} else {
update.next = queue.pending.next;
queue.pending.next = update;
}
queue.pending = update;
schedule(); // 重新render 组件
}
window.app = schedule();