//是否是第一次加載
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();
模擬實現(xiàn)hook useState
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
- 文/潘曉璐 我一進店門瘦真,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人黍瞧,你說我怎么就攤上這事吗氏。” “怎么了雷逆?”我有些...
- 文/不壞的土叔 我叫張陵,是天一觀的道長污尉。 經(jīng)常有香客問我膀哲,道長,這世上最難降的妖魔是什么被碗? 我笑而不...
- 正文 為了忘掉前任某宪,我火速辦了婚禮,結(jié)果婚禮上锐朴,老公的妹妹穿的比我還像新娘兴喂。我一直安慰自己,他們只是感情好焚志,可當我...
- 文/花漫 我一把揭開白布衣迷。 她就那樣靜靜地躺著,像睡著了一般酱酬。 火紅的嫁衣襯著肌膚如雪壶谒。 梳的紋絲不亂的頭發(fā)上,一...
- 文/蒼蘭香墨 我猛地睜開眼菌瘪,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了录平?” 一聲冷哼從身側(cè)響起麻车,我...
- 正文 年R本政府宣布,位于F島的核電站盯桦,受9級特大地震影響慈俯,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜拥峦,卻給世界環(huán)境...
- 文/蒙蒙 一贴膘、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧略号,春花似錦刑峡、人聲如沸。這莊子的主人今日做“春日...
- 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至羽利,卻和暖如春阳似,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背铐伴。 一陣腳步聲響...
推薦閱讀更多精彩內(nèi)容
- 模擬useState 要點 _下劃線代表內(nèi)部的變量 const currentIndex = _index; 緩存...
- 當然,useState的源碼不是上面那么寫的梯浪。但是其中的思想是一致的捌年,無非就是利用數(shù)組或者表(源碼是鏈表)將每個s...
- 背景 React 16.8 引入了 Hook[https://zh-hans.reactjs.org/docs/h...
- const [text, setText] = useState(0);初始化text=0礼预;setText是唯一能...