模擬實現(xiàn)hook useState

//是否是第一次加載
let isMount = true;
//fiber 鏈表指針
let workInProgressHook = null;

//每個組件對應(yīng)一個fiber對象
let fiber = {
    //保存組件函數(shù)
    stateNode:App,
    //保存組件對應(yīng)的hooks 數(shù)據(jù)鏈表
    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{
        //更新阻星,非第一次加載
        //設(shè)置當前hook對象
        hook = workInProgressHook;
        //指針后移
        workInProgressHook = hook.next;
    }
    //獲取hook對應(yīng)的值
    let baseState = hook.memoizedState;

    //需要更新,環(huán)狀鏈表遍歷
    if(hook.queue.pending){
        // 獲取update環(huán)狀單向鏈表中第一個update
        let firstUpdate = hook.queue.pending.next;
        do {
            // 執(zhí)行update action
            const action = firstUpdate.action;
            baseState = action(baseState);
            firstUpdate = firstUpdate.next;
            // 最后一個update執(zhí)行完后跳出循環(huán)
          } while (firstUpdate !== hook.queue.pending.next);
    }
    //重新給hook 賦值
    hook.memoizedState = baseState;
    return [baseState,dispatchAction.bind(null,hook.queue)]

}

//memoizedState更新方法
function dispatchAction(queue,action){
    //創(chuàng)建要更新的鏈表(環(huán)狀)
     const update = {
         action:action,
         next:null
     }
     //與當前hook的操作對象queue關(guān)聯(lián)
     //當前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;
    //模擬調(diào)度
    schedule();
}



//初始化調(diào)度render函數(shù)
function schedule(){
    //指針指到第一個節(jié)點
    workInProgressHook = fiber.memoizedState;
    isMount = false;
    //觸發(fā)組件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();

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市已添,隨后出現(xiàn)的幾起案子妥箕,更是在濱河造成了極大的恐慌,老刑警劉巖更舞,帶你破解...
    沈念sama閱讀 218,122評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件畦幢,死亡現(xiàn)場離奇詭異,居然都是意外死亡缆蝉,警方通過查閱死者的電腦和手機宇葱,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,070評論 3 395
  • 文/潘曉璐 我一進店門瘦真,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人黍瞧,你說我怎么就攤上這事吗氏。” “怎么了雷逆?”我有些...
    開封第一講書人閱讀 164,491評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長污尉。 經(jīng)常有香客問我膀哲,道長,這世上最難降的妖魔是什么被碗? 我笑而不...
    開封第一講書人閱讀 58,636評論 1 293
  • 正文 為了忘掉前任某宪,我火速辦了婚禮,結(jié)果婚禮上锐朴,老公的妹妹穿的比我還像新娘兴喂。我一直安慰自己,他們只是感情好焚志,可當我...
    茶點故事閱讀 67,676評論 6 392
  • 文/花漫 我一把揭開白布衣迷。 她就那樣靜靜地躺著,像睡著了一般酱酬。 火紅的嫁衣襯著肌膚如雪壶谒。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,541評論 1 305
  • 那天膳沽,我揣著相機與錄音汗菜,去河邊找鬼。 笑死挑社,一個胖子當著我的面吹牛陨界,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播痛阻,決...
    沈念sama閱讀 40,292評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼菌瘪,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了录平?” 一聲冷哼從身側(cè)響起麻车,我...
    開封第一講書人閱讀 39,211評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎斗这,沒想到半個月后动猬,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,655評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡表箭,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,846評論 3 336
  • 正文 我和宋清朗相戀三年赁咙,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,965評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡彼水,死狀恐怖崔拥,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情凤覆,我是刑警寧澤链瓦,帶...
    沈念sama閱讀 35,684評論 5 347
  • 正文 年R本政府宣布,位于F島的核電站盯桦,受9級特大地震影響慈俯,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜拥峦,卻給世界環(huán)境...
    茶點故事閱讀 41,295評論 3 329
  • 文/蒙蒙 一贴膘、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧略号,春花似錦刑峡、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,894評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至羽利,卻和暖如春阳似,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背铐伴。 一陣腳步聲響...
    開封第一講書人閱讀 33,012評論 1 269
  • 我被黑心中介騙來泰國打工撮奏, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人当宴。 一個月前我還...
    沈念sama閱讀 48,126評論 3 370
  • 正文 我出身青樓畜吊,卻偏偏與公主長得像,于是被迫代替她去往敵國和親户矢。 傳聞我的和親對象是個殘疾皇子玲献,可洞房花燭夜當晚...
    茶點故事閱讀 44,914評論 2 355

推薦閱讀更多精彩內(nèi)容