//mini useState的实现 let isMount = true; let workInProgressHook = null; const fiber = { stateNode: App, //保存的是一条链表 memorizeState: null } function useState(initialState) { //useState对应的是哪个hook呢 let hook; if(isMount) { //首次渲染 hook = { memorizeState: initialState, next: null, queue: { pedding: null } } if(!fiber.memorizeState) { fiber.memorizeState = hook; }else { workInProgressHook.next = hook; } workInProgressHook = hook; }else { hook = workInProgressHook; workInProgressHook = workInProgressHook.next; } //将环状链表剪开,计算新的state let baseState = hook.memorizeState; if(hook.queue.pedding) { let firstUpdate = hook.queue.pedding.next; do{ const action = firstUpdate.action; baseState = action(baseState) firstUpdate = firstUpdate.next; }while(firstUpdate !== hook.queue.pedding.next) hook.queue.pedding = null; } hook.memorizeState = baseState; //bind函数第二个参数相当于给dispatchAction加了默认值 return [baseState, dispatchAction.bind(null, hook.queue)]; } function dispatchAction(queue, action) { const update = { action, next: null } if(queue.pedding === null) { //环状链表,因为真实react中,每次更新是有优先级的 //u0 -> u0 ->u0 update.next = update; }else { //多次调用 //u0 -> u0 //u1 -> u0 -> u1 update.next = queue.pedding.next; queue.pedding.next = update; } queue.pedding = update; schedule(); } function schedule() { //每次更新都会触发一次调度 workInProgressHook = fiber.memorizeState; const app = fiber.stateNode(); isMount = false; return app; } function App() { const [num, updateNum] = useState(0); const [num2, updateNum2] = useState(0); console.log('isMount', isMount) console.log('num', num) console.log('num2', num2) return { onClick() { updateNum(num => num + 1); }, onClick2() { updateNum2(num => num + 10); } } } window.app = schedule();
在App中,可以创建多个useState的hook,因为都是调用useState,那么怎么知道调用的是哪个hook,并且每次都按顺序调用呢,思路就是使用链表来保存多个hook。
ps:参照卡颂大佬的课程学习的