根据源码实现简易版hooks(useState)

简易版hooks的实现(useState)

90行代码==按照hooks源码逻辑实现的简易版的useState,去除了优先级,实现了多个state
其他hooks的实现也跟这个差不多,只是执行的时间不同以及memoizeState保存的数据不同而已

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script>
  let isMount = true;
  let workInProgressHook = null;//全局变量,指向当前的正在执行的hooks

  const fiber = {
    memoizedState: null,
    stateNode: App
  };

  function run() {
    workInProgressHook = fiber.memoizedState;
    const app = fiber.stateNode();
    isMount = false;
    return app;
  }

  function dispatchAction(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;
    run();
  }

  function useState(initialState) {
    let hook;
    if (isMount) {
      hook = {
        queue: {
          pending: null
        },
        memoizedState: initialState,
        next: null
      };

      if (!fiber.memoizedState) {
        fiber.memoizedState = hook;
      } else {
        workInProgressHook.next = hook;
      }
      workInProgressHook = hook;
    } else {
      hook = workInProgressHook;
      workInProgressHook = workInProgressHook.next;
    }

    let baseState = hook.memoizedState;
    if (hook.queue.pending) {
      let firstUpdate = hook.queue.pending.next;
      // hook.queue.pending保存着最后一个update,所以它的next是第一个update

      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)]

  }

  function App() {
    const [num, updateNum] = useState(0);
    const [states, triggerState] = useState(true);
    console.log("isMount?", isMount);
    console.log('num', num);
    console.log('states', states);
    return {
      onclick() {
        updateNum(num => num + 1);
      },
      trigger() {
        triggerState(states =>  !states);
      }
    }
  }

  window.app = run();
</script>
</body>
</html>

在这里插入图片描述
多次调用onclick只改变了num的值,states的值不改变,多次调用trigger只改变了states的值,num的值不改变,所以两个状态是互相不干扰的,实现了useState的功能!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值