Hook 是 React 16.8 的新增特性。它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性。 下面有个一个参考实现usestate的案例
let isMount = true;
let workInProgressHook = null;
const fiber = {
stateNode: App,
memoizedState: null,
};
function userState(initialState) {
let hook;
if (isMount) {
hook = {
memoizedState: initialState,
next: null, //下一个hook
queue: {
pending: null,//需要更新的update
},
};
if (!fiber.memoizedState) {
fiber.memoizedState = hook;
} else {
workInProgressHook.next = hook;
}
workInProgressHook = hook;
} else {
console.log(`initialState:${initialState}`);
hook = workInProgressHook;
workInProgressHook = workInProgressHook.next;
}
//todo
debugger
let baseState = hook.memoizedState;
if (hook.queue.pending) {
console.log(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.memoizedState = baseState;
return [baseState, dispatchAction.bind(null, hook.queue)];
}
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(); //触发更新
}
function schedule() {
workInProgressHook = fiber.memoizedState;
const app = fiber.stateNode();
isMount = false;
return app;
}
function App() {
const [num, updateNum] = userState(0);
const [num1, updateNum1] = userState(1);
// const [num2, updateNum2] = userState(2);
// const [num3, updateNum3] = userState(3);
// const [num, updateNum] = userState(0);
console.log(`num:${num},num1:${num1}`);
return {
onClick() {
// updateNum((num) => num + 1);
updateNum((num) => num + 1);
},
onClick1() {
updateNum1((num) => num + 2);
},
onClick2() {
},
};
}
window.app = schedule();