当前位置:首页 > JavaScript

js 实现hooks

2026-03-15 08:57:20JavaScript

如何在 JavaScript 中实现类似 React Hooks 的功能

Hooks 是 React 中用于在函数组件中管理状态和副作用的机制。在纯 JavaScript 中实现类似功能需要理解闭包、状态管理和副作用处理等概念。

基本 useState 实现

一个简单的 useState 实现可以通过闭包来保存状态:

js 实现hooks

let state;
function useState(initialValue) {
  state = state || initialValue;
  function setState(newValue) {
    state = newValue;
    // 这里需要触发重新渲染
  }
  return [state, setState];
}

更完整的实现

为了支持多个状态变量,需要改进实现:

js 实现hooks

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

注意事项

  1. 这种实现是简化版,React 的实际实现更复杂,考虑了更多边界情况
  2. 每次渲染前需要重置 hook 索引
  3. 在实际应用中需要处理组件卸载时的清理工作
  4. 这种实现不适用于并发模式

以上代码展示了如何在纯 JavaScript 中实现类似 React Hooks 的基本功能。真正的 React Hooks 实现涉及更多细节,包括调度、批处理更新和更复杂的依赖比较逻辑。

标签: jshooks
分享给朋友:

相关文章

js实现打印

js实现打印

使用window.print()方法实现打印 在JavaScript中,可以通过调用window.print()方法直接触发浏览器的打印功能。这会打开系统的打印对话框,用户可以选择打印机和设置打印选项…

js 进度条的实现

js 进度条的实现

使用 HTML 和 CSS 创建基础进度条 HTML 结构可以简单使用一个 div 元素作为容器,内部嵌套另一个 div 表示进度: <div class="progress-containe…

js实现投球

js实现投球

实现投球动画的基本思路 使用JavaScript和CSS动画结合的方式模拟投球效果。核心是通过改变元素的位置、旋转和缩放属性,配合定时器或CSS过渡实现平滑动画。 创建基础HTML结构 <di…

js实现代码雨

js实现代码雨

实现代码雨效果 使用HTML5 Canvas和JavaScript可以轻松实现经典的代码雨效果。以下是完整的实现代码和说明: HTML结构 <!DOCTYPE html> <…

js进度条实现

js进度条实现

使用HTML和CSS创建基础结构 在HTML中创建一个容器元素用于显示进度条,通常使用<div>元素。CSS用于设置进度条的样式,包括宽度、高度、颜色和圆角等属性。 <div cl…

js实现显示隐藏

js实现显示隐藏

显示隐藏的实现方法 在JavaScript中,实现元素的显示和隐藏可以通过多种方式完成。以下是几种常见的方法: 修改CSS的display属性 通过改变元素的display属性可以在none(隐藏)…