<html>
<head></head>
<body></body>
<script>
let isMount = true; //判断组件是mount还是update
let workInProgressHook = null; //链接链表的hook
// 每个组件对应一个fiber
const fiber = {
stateNode: App, //保存对应的组件
memorizedState: null //链表的形式保存对应的state
}
function useState(initialState) {
// 获取当前是哪个hook
let hook;
if (isMount) {
hook = {
memorizedState: initialState,
next: null, //是链表指向下一个hook
queue: { //保存新的状态 dispatchAction中的第一个参数
pending: null
},
}
if (!fiber.memorizedState) {
fiber.memorizedState = hook;
} else {
workInProgressHook.next = hook;
}
workInProgressHook = hook;
} else {
hook = workInProgressHook;
workInProgressHook = workInProgressHook.next;
}
// 基于baseState产生新的状态
let baseState = hook.memorizedState;
if (hook.queue.pending) {
let firstUpdate = hook.queue.pending.next;
do {
const action = firstUpdate.action;
baseState = action(baseState);
firstUpdate = firstUpdate.next;
} while (firstUpdate !== hook.queue.pending.next)
hook.queue.pending = null;
}
hook.memorizedState = baseState;
return [baseState, dispatchAction.bind(null, hook.queue)]
}
function dispatchAction(queue, action) {
const update = {
action,
next: null
}
if (queue.pending === null) {
// u0 ->u0 ->u0
update.next = update; //环状链表
} else {
// u0->u0
//u1->u0->u1将新的节点插入
update.next = queue.pending.next
queue.pending.next = update;
}
queue.pending = update;
schedule()
}
function schedule() {
workInProgressHook = fiber.memorizedState;
const app = fiber.stateNode();
isMount = false;
return app;
}
function App() {
const [num, updateNum] = useState(0);
const [num1, updateNum1] = useState(10);
console.log('isMount:', isMount);
console.log('num:', num);
console.log('num1:', num1);
return {
onClick() {
updateNum(num => num + 1)
},
onFocus() {
updateNum1(num => num + 10)
}
}
}
window.app = schedule();
// app.onClick()
// app.onFocus()
</script>
</html>
react hook 源码解析
最新推荐文章于 2024-07-10 10:28:12 发布