关于javascript:ReactuseState实现

40次阅读

共计 1884 个字符,预计需要花费 5 分钟才能阅读完成。

已实现性能

  • 实现 useState 的基本功能,取值和存值

待优化解决问题

  • 在某个时间段,将要更新的状态对立解决完,再更新 DOM,目前是更新一次从新渲染一次
  • 临时不能引入到 React 环境中,短少 React 的渲染办法待实现。但能够 window 中调试,能看到状态的更新
/**
 * 第一步:* isMount: 判断是第一次加载还是更新组件
 * workInProgressHooks: 定义一个指针,指向以后执行的 useSate 的
 */

 let isMount = true;
 let workInProgressHooks = null;
 
 /**
  *  第二步
  *  定义 fiber 节点
  */
 const fibier = {
   stateNode: App,
   memoizedState: null, // 以后 fiber 节点须要保护的 hook
 };
 
 /**
  * 第四步:实现 useState
  * @returns
  */
 
 function useState(initialState) {
   let hook;
    if(typeof initialState === "function") {initialState = initialState();
    }
 
   if (isMount) {  
     hook = {
       memoizedState: initialState, // 以后这个 hook 须要保护的数据
       next: null, // 为保障所有的 useState 能按序执行,所以须要实现【链表构造】queue: {pending: null,},
     };
 
     if (!fibier.memoizedState) {fibier.memoizedState = hook;} else {workInProgressHooks.next = hook;}
     workInProgressHooks = hook;
   } else {
     hook = workInProgressHooks;
     workInProgressHooks = workInProgressHooks.next;
   }
 
   // todo
   let beaseSate = hook.memoizedState;
   if(hook.queue.pending) {
     let firstUpate = hook.queue.pending.next;
     do{
       const action = firstUpate.action;
       beaseSate = action(beaseSate);
       firstUpate = firstUpate.next;

     }while(firstUpate !== hook.queue.pending.next);
 
     hook.queue.pending = null;  
   }
 
   hook.memoizedState = beaseSate;
   return [beaseSate, dispatchAction.bind(null, hook.queue)]
 
 }
 
 /**
  * 第五步:实现状态更新
  * @returns
  */
 
 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;
    schedule();}
 
 /**
  * 第三步
  * 实现 React 调度办法
  * 调度办法运行后,即从新加载组建后,React 会从新渲染
  */
 function schedule() {
   workInProgressHooks = fibier.memoizedState;
   const app = fibier.stateNode();
   isMount = false;
   return app;
 }
 
 
 function App() {const [num1, setNum1] = useState(0);
   const [num2, setNum2] = useState(1);
   const [num3, setNum3] = useState(2);

   console.log("---- 最近一次更新 --------",);
   console.log("num1---", num1);
   console.log("num2-", num2);
   console.log("num3222", num3);

   return {onclick() {setNum1(num1 => num1 +1);
        setNum2(num2 => num2+1)
        setNum3(num3 => num3 +1)
      }
   }
 }
 window.app = schedule();
 
 
 export default App;
 
 

正文完
 0