reactHook useState实现原理

说实话,是个正常人都看不懂

let isMount = true;
//一个指针,指向当前的hook
let workInProgressHook=null;

const fiber = {
  //保存的是这个函数本身
  stateNode:App,
  //保存对应的hooks的数据的
  memoizedState:null
}

//每个useState都会,创建一个hook
//并且通过workInProgressHook.next
//串成一个链表
//有很多useState 那我们怎么知道当前useState对应的那个hook?

function useState(initialState) {
  let hook;
  if(isMount){
    //他是一个链表,单向链表
    hook={
      //initalState 就是useState初始化的时候定义的值
      memoizedState: initialState,
      next:null,
      //保存触发更新的函数
      queue:{
        pending:null
      }
    }
    //考虑第一次渲染,第一个useState
    if(!fiber.memoizedState){
      fiber.memoizedState=hook; 
    }else{
      //else考虑第一次渲染,后续的多个useState

      //取得上一次的workInProgressHook他的next=当前hook
      workInProgressHook.next=hook;
    }
       workInProgressHook=hook;
  }else{
    //在updata时
    //(在这里需要解释一下hook和当前hook的区别么?)
     //hook = workInProgressHook(理解为当前hook)
    hook=workInProgressHook;
    //当前hook=当前hook.next 
    //下一次再进来,就按顺序了
    workInProgressHook=workInProgressHook.next;
  }

  //取到了 当前useState的数据,
  //基于当前的数据做一些处理
  let baseState = hook.memoizedState;
  //代表需要更新
  if(hook.queue.pending){
    // hook.queue.pending是最后一个
    //所以.next 是第一个
    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.memoizedState = baseState;
  return [baseState,dispatchAction.bind(null,hook.queue)]
}

//dispatchAction就是setState的函数
//我们怎么知道dispatchAction对应的那个useState呢?
function dispatchAction(queue,action) {
  //创建一个更新
  const update = {
    action,
    next:null
  }

  //每次更新完,都清空了,所以永远是null
  if(queue.pending === null){
    //自己指向自己,形成一个环形链表
    update.next = update;
  }else{
      // u0->u0
      //U1 -> U0 -> U1
      update.next =  queue.pending.next
      queue.pending.next=update
  }

  //每次 都是当前的update
  queue.pending = update;
  schedule();
}


//调度 ,每次更新都会触发调度,组件就会重新runder
  function schedule(){
    //指针重新指向 链表的第一个
    workInProgressHook=fiber.memoizedState

    //首次调用
    const app =  fiber.stateNode();
    isMount=false;
    return app;

}

function App (){
  const [num,updateNum] = useState(0);
  return {
    onClick(){
      updateNum((num)=>num+1);
      updateNum((num)=>num+2);
    }
  }
}

window.app = schedule();
app.onClick()
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值