js实现hooks
实现自定义 Hooks 的基本方法
在 JavaScript 中实现类似 React Hooks 的功能,可以通过闭包和状态管理来模拟。以下是一个简单的 useState 实现示例:
let state = [];
let setters = [];
let stateIndex = 0;
function createSetter(index) {
return function(newState) {
state[index] = newState;
render();
};
}
function useState(initialState) {
state[stateIndex] = state[stateIndex] ?? initialState;
setters[stateIndex] = setters[stateIndex] ?? createSetter(stateIndex);
const currentState = state[stateIndex];
const currentSetter = setters[stateIndex];
stateIndex++;
return [currentState, currentSetter];
}
function render() {
stateIndex = 0;
// 重新渲染组件的逻辑
}
实现 useEffect Hook
useEffect 的实现需要考虑依赖项比较和清理函数:

let effectDeps = [];
let effectIndex = 0;
function useEffect(callback, deps) {
const hasNoDeps = !deps;
const currentDeps = effectDeps[effectIndex];
const hasChangedDeps = currentDeps ? !deps.every((dep, i) => dep === currentDeps[i]) : true;
if (hasNoDeps || hasChangedDeps) {
if (effectDeps[effectIndex]) {
// 清理上一次的 effect
const cleanup = effectDeps[effectIndex].cleanup;
if (cleanup) cleanup();
}
const cleanup = callback();
effectDeps[effectIndex] = {
deps,
cleanup
};
}
effectIndex++;
}
实现 useReducer Hook
useReducer 是更复杂的状态管理 Hook:
function useReducer(reducer, initialState) {
const [state, setState] = useState(initialState);
function dispatch(action) {
const newState = reducer(state, action);
setState(newState);
}
return [state, dispatch];
}
实现自定义 Hook 的规则
自定义 Hook 需要遵循 React Hooks 的规则:

- 只在函数组件或自定义 Hook 中调用 Hook
- 不要在循环、条件或嵌套函数中调用 Hook
- 使用
use前缀命名自定义 Hook
示例自定义 Hook
实现一个获取窗口大小的自定义 Hook:
function useWindowSize() {
const [size, setSize] = useState({
width: window.innerWidth,
height: window.innerHeight
});
useEffect(() => {
function handleResize() {
setSize({
width: window.innerWidth,
height: window.innerHeight
});
}
window.addEventListener('resize', handleResize);
return () => window.removeEventListener('resize', handleResize);
}, []);
return size;
}
注意事项
这些实现是简化的版本,实际 React Hooks 的实现更复杂:
- React 使用链表而不是数组来管理 Hook
- 需要考虑并发渲染和批量更新
- 有更完善的错误处理和开发工具支持
在实际项目中,建议直接使用 React 提供的 Hooks API,而不是自行实现。






