- 在某个时间段,将要更新的状态对立解决完,再更新 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;