js 实现hooks
如何在 JavaScript 中实现类似 React Hooks 的功能
Hooks 是 React 中用于在函数组件中管理状态和副作用的机制。在纯 JavaScript 中实现类似功能需要理解闭包、状态管理和副作用处理等概念。
基本 useState 实现
一个简单的 useState 实现可以通过闭包来保存状态:
let state;
function useState(initialValue) {
state = state || initialValue;
function setState(newValue) {
state = newValue;
// 这里需要触发重新渲染
}
return [state, setState];
}
更完整的实现
为了支持多个状态变量,需要改进实现:
let hookStates = [];
let currentIndex = 0;
function useState(initialValue) {
const index = currentIndex++;
hookStates[index] = hookStates[index] || initialValue;
const setState = (newValue) => {
hookStates[index] = newValue;
// 触发重新渲染
render();
};
return [hookStates[index], setState];
}
function render() {
currentIndex = 0; // 重置索引
// 执行组件渲染逻辑
}
useEffect 实现
实现一个简单的 useEffect:
let effectDeps = [];
function useEffect(callback, deps) {
const index = currentIndex++;
const hasNoDeps = !deps;
const oldDeps = effectDeps[index];
const hasChangedDeps = oldDeps
? !deps.every((dep, i) => dep === oldDeps[i])
: true;
if (hasNoDeps || hasChangedDeps) {
callback();
effectDeps[index] = deps;
}
currentIndex++;
}
完整示例
结合以上概念的一个完整示例:

let states = [];
let effects = [];
let currentStateIndex = 0;
let currentEffectIndex = 0;
function resetHooks() {
currentStateIndex = 0;
currentEffectIndex = 0;
}
function useState(initialValue) {
const index = currentStateIndex++;
states[index] = states[index] || initialValue;
const setState = (newValue) => {
states[index] = newValue;
// 模拟重新渲染
render();
};
return [states[index], setState];
}
function useEffect(callback, deps) {
const index = currentEffectIndex++;
const hasNoDeps = !deps;
const oldDeps = effects[index];
const hasChangedDeps = oldDeps
? !deps.every((dep, i) => dep === oldDeps[i])
: true;
if (hasNoDeps || hasChangedDeps) {
callback();
effects[index] = deps;
}
}
function render() {
resetHooks();
// 组件渲染逻辑
}
使用示例
function Counter() {
const [count, setCount] = useState(0);
useEffect(() => {
console.log(`Count changed to ${count}`);
}, [count]);
return {
click: () => setCount(count + 1),
getCount: () => count
};
}
const counter = Counter();
counter.click(); // 触发重新渲染
console.log(counter.getCount()); // 1
注意事项
- 这种实现是简化版,React 的实际实现更复杂,考虑了更多边界情况
- 每次渲染前需要重置 hook 索引
- 在实际应用中需要处理组件卸载时的清理工作
- 这种实现不适用于并发模式
以上代码展示了如何在纯 JavaScript 中实现类似 React Hooks 的基本功能。真正的 React Hooks 实现涉及更多细节,包括调度、批处理更新和更复杂的依赖比较逻辑。






