很久没学习过react了,当时刚了解了hooks时,就感觉这种用法很神奇,也猜想了一下背后的实现原理,今天正好要正式学习一下,所以把自己的猜想先用伪代码写一下,后续可以看看源码到底是怎么实现的。
hooks使用官方给了两个限制规则:
- 只能在函数最外层调用 Hook。不要在循环、条件判断或者子函数中调用。
- 只能在 React 的函数组件中调用 Hook。不要在其他 JavaScript 函数中调用。
从这个规则里大概也能窥测到一点原理。
我们拿useState来说, useState可以使用多次,但要按顺序(不能条件判断),useState每次返回不同,但是按第一次使用的顺序返回,这应该是个状态机(没了解过,猜的)。直接上码分析:
const states = Object.create(null); // 存放state的地方
const componentId = 1; // 每个组件有个id
let stateId = 0; // 每个组件可以有多个state(多次调用useState)
function useState(defaultValue) {
stateId += 1;
if (states[componentId] && states[componentId][stateId]) {
return states[componentId][stateId];
}
if (!states[componentId]) {
states[componentId] = Object.create(null);
}
const state = [defaultValue];
function setter(value) {
state[0] = value; // 简单替换
}
state[1] = setter;
states[componentId][stateId] = state;
return state;
}
function Example() {
const [count, setCount] = useState(0);
console.log("count =", count);
setCount(count + 1);
const [age, setAge] = useState(42);
console.log("age = ", age);
setAge(age + 1);
console.log(" ");
console.log("----------");
console.log(" ");
return "hello world";
}
// react知道当前渲染的组件id, 所以能从states里找到对应的state
function render() {
Example();
stateId = 0;
}
// 组件卸载,销毁state
function destroy() {
delete states[componentId];
console.log("destroyed");
console.log(" ");
console.log("----------");
console.log(" ");
}
render();
render();
render();
destroy();
render();
render();
render();
输出结果:

是符合预期的,我们取到了对应的值,还可以更新
可能现在的猜想完全不对,毕竟才看到了使用,文档都没读完呢,后续再学习一下,完善