代码拉取完成,页面将自动刷新
同步操作将从 北鸟南游/react_hooks_fiber 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
// https://www.bilibili.com/video/BV1iV411b7L1
// 区分组件是 mount首次渲染, 还是 update更新
let isMount = true;
let workingProgressHook = null;
// 定义fiber数据结构
const fiber = {
stateNode: App, // stateNode保存着App组件本身
memoizedState: null, //memoizedState 保存hooks数据
};
// 执行fiber调度
function schedule() {
workingProgressHook = fiber.memoizedState;
const app = fiber.stateNode(); //相当于触发组件render,执行App()
isMount = false; //首次调用之后,状态就是更新
return app;
}
// 定义useState
function useState(initialState) {
let hook;
// 区分首次渲染还是更新
if (isMount) {
//挂载
hook = {
memoizedState: initialState,
next: null,
queue: {
pending: null,
},
};
if (!fiber.memoizedState) {
// 第一次调用useState
fiber.memoizedState = hook;
} else {
// 将多次调用的useState的hook进行串连
workingProgressHook.next = hook;
}
workingProgressHook = hook;
} else {
// update的过程
hook = workingProgressHook;
workingProgressHook = workingProgressHook.next;
}
let baseState = hook.memoizedState;
if (hook.queue.pending) {
// 第一个update
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.memoizedState = baseState;
// bind 的第一个参数会作为原函数运行时的 this 指向
// 第二个开始的参数是可选的,当绑定函数被调用时,这些参数加上绑定函数本身的参数会按照顺序作为原函数运行时的参数
// 所以会把 updateNum函数内定义的函数作为参数进行传递给函数调用的时候
return [baseState, dispatchAction.bind(null, hook.queue)];
}
function dispatchAction(queue, action) {
const update = { action, next: null };
if (queue.pending === null) { // 还没有链表关系
// 创建环状链表
update.next = update;
} else { //已经调用一次 updateNum 函数,如果后边有多次调用updateNum函数
// queue.pending 已经存在;update是新插入的;
// update.next被赋值为queue.pending.next,说明将update.next指向原链表的头,【queue.pending表示尾,.next表示头】
update.next = queue.pending.next;
// 更新链表头
queue.pending.next = update;
}
// queue.pending为链表的最后一个update
queue.pending = update;
schedule();
}
function App() {
const [num, updateNum] = useState(0);
const [numA, updateNumA] = useState(0);
console.log("isMount", isMount);
console.log("num", num);
console.log("numA", numA);
return {
onClick() {
updateNum((num) => num + 1);
},
onFocus() {
updateNumA((num) => num + 10);
},
};
}
// 把schedule函数挂载到全局对象window的app属性上,这样可以全局获取到
window.app = schedule();
// 在控制台,通过调用app.onClick 和app.onFocus观察hooks的执行
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。