模拟实现hook useState

//是否是第一次加载
let isMount = true;
//fiber 链表指针
let workInProgressHook = null;

//每个组件对应一个fiber对象
let fiber = {
    //保存组件函数
    stateNode:App,
    //保存组件对应的hooks 数据链表
    memoizedState:null

}

function useState(initialState){
    //生成一个hook 对象
    let hook;
    if(isMount){
       //第一次加载初始化hook对象
       hook = {
         memoizedState:initialState,
         next:null,
         queue:{
            pending:null
         }   
       }
       //当是第一个useState的时候     
       if(!fiber.memoizedState){
           fiber.memoizedState = hook;
       }else{
           //挂在到最后一个
            workInProgressHook.next = hook;
       }
       //移动指针到最后一个
       workInProgressHook = hook;
    }else{
        //更新,非第一次加载
        //设置当前hook对象
        hook = workInProgressHook;
        //指针后移
        workInProgressHook = hook.next;
    }
    //获取hook对应的值
    let baseState = hook.memoizedState;

    //需要更新,环状链表遍历
    if(hook.queue.pending){
        // 获取update环状单向链表中第一个update
        let firstUpdate = hook.queue.pending.next;
        do {
            // 执行update action
            const action = firstUpdate.action;
            baseState = action(baseState);
            firstUpdate = firstUpdate.next;
            // 最后一个update执行完后跳出循环
          } while (firstUpdate !== hook.queue.pending.next);
    }
    //重新给hook 赋值
    hook.memoizedState = baseState;
    return [baseState,dispatchAction.bind(null,hook.queue)]

}

//memoizedState更新方法
function dispatchAction(queue,action){
    //创建要更新的链表(环状)
     const update = {
         action:action,
         next:null
     }
     //与当前hook的操作对象queue关联
     //当前hook没有更新
     if(!queue.pending){
         //u0 -> u0
         update.next = update;
     }else{
         //u1 -> u0 ->u1
         update.next = queue.pending.next;
         queue.pending.next = update;
     }
     queue.pending = update;
    //模拟调度
    schedule();
}



//初始化调度render函数
function schedule(){
    //指针指到第一个节点
    workInProgressHook = fiber.memoizedState;
    isMount = false;
    //触发组件render
    fiber.stateNode();
}






function App(){
    const [num,updateNum] = useState(0);
    const [num1,updateNum1] = useState(1);
    console.log(num,num1);
    return {
        click:()=>{
            updateNum(num=>num+1);
        }
    }
    
}
var test = App();
test.click();

你可能感兴趣的:(模拟实现hook useState)