美文网首页
模拟实现hook useState

模拟实现hook useState

作者: _嘿嘿_ | 来源:发表于2021-07-30 18:31 被阅读0次
//是否是第一次加载
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

  • 模拟实现useState

    当然,useState的源码不是上面那么写的。但是其中的思想是一致的,无非就是利用数组或者表(源码是链表)将每个s...

  • Composition API和React Hook的区别

    从React Hook的实现角度看,React Hook是根据useState调用的顺序来确定下一次重渲染时的st...

  • useState Hook

    前言问题:Hook 是什么? 一个 Hook 就是一个特殊的函数,让你在函数组件中获取状态等 React 特性使用...

  • React Hook 新特性的初体验

    React 提供 Hook Api useState 类型: string | number | boolean ...

  • useState

    1. useState解析  useState来自react,需要从react中导入,它是一个hook;✓ 参数...

  • useState & useReducer

    useState 在 React 函数组件中存储内部 state 通常会使用 useState hook 传入一个...

  • React Hook

    Hook 简介 State Hook React 假设当你多次调用 useState 的时候,你能保证每次渲染时它...

  • React hook的useState 简易实现

    模拟useState 要点 _下划线代表内部的变量 const currentIndex = _index; 缓存...

  • 新手在React中遇到的问题

    1、construtor里可以有什么? 但是在应用hook时,不能把hook中的useState写入constru...

网友评论

      本文标题:模拟实现hook useState

      本文链接:https://www.haomeiwen.com/subject/rjecvltx.html