当前位置:首页 > JavaScript

js实现reacthooks

2026-02-01 14:28:52JavaScript

实现 React Hooks 的 JavaScript 核心逻辑

React Hooks 的核心是通过闭包和链表管理状态,以下是一个简化版的 useStateuseEffect 实现:

js实现reacthooks

基础 Hook 系统结构

let currentHook = 0;
let workInProgressHook = null;
let isMount = true;

const fiber = {
  memoizedState: null, // 链表头节点
  stateNode: null,
};

useState 简化实现

function useState(initialState) {
  let hook;
  if (isMount) {
    hook = {
      memoizedState: typeof initialState === 'function' 
        ? initialState() 
        : initialState,
      next: null,
      queue: { pending: null },
    };
    if (!fiber.memoizedState) {
      fiber.memoizedState = hook;
    } else {
      workInProgressHook.next = hook;
    }
    workInProgressHook = hook;
  } else {
    hook = workInProgressHook;
    workInProgressHook = workInProgressHook.next;
  }

  let baseState = hook.memoizedState;
  if (hook.queue.pending) {
    let firstUpdate = hook.queue.pending.next;
    do {
      const action = firstUpdate.action;
      baseState = typeof action === 'function' 
        ? action(baseState) 
        : action;
      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;
}

useEffect 简化实现

function useEffect(callback, deps) {
  const hook = {
    memoizedState: null,
    next: null,
    effect: {
      create: callback,
      deps,
      destroy: undefined,
    },
  };

  if (!fiber.memoizedState) {
    fiber.memoizedState = hook;
  } else {
    workInProgressHook.next = hook;
  }
  workInProgressHook = hook;

  if (!isMount) {
    const prevEffect = workInProgressHook.memoizedState;
    if (deps && deps.some((dep, i) => dep !== prevEffect.deps[i])) {
      prevEffect.destroy?.();
      const effect = { create: callback, deps, destroy: undefined };
      workInProgressHook.memoizedState = effect;
      effect.destroy = effect.create();
    }
  }
}

渲染调度模拟

function schedule() {
  workInProgressHook = fiber.memoizedState;
  currentHook = 0;
  isMount = false;
  // 这里实际会触发组件重新渲染
}

实际使用示例

function Counter() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    console.log(`Count updated to ${count}`);
    return () => console.log('Cleanup');
  }, [count]);

  return {
    click: () => setCount(c => c + 1),
    log: () => console.log(count),
  };
}

// 首次渲染
const counter = Counter(); // 控制台输出: Count updated to 0
counter.click(); // 触发更新
schedule(); // 模拟重新渲染
counter.log(); // 输出: 1

关键实现要点

  1. 链表结构存储:每个 Hook 通过 next 指针形成链表,保证在多次调用时能正确获取对应状态
  2. 队列更新机制:状态更新通过环形链表实现批处理
  3. 依赖比较useEffect 通过浅比较决定是否执行副作用
  4. 执行时机:副作用清理和创建函数在适当时机被调用

注意这仅是简化实现,真实 React 的实现还包含调度器、优先级、错误边界等复杂机制。完整实现可参考 React 源码中的 ReactFiberHooks.js 文件。

标签: jsreacthooks
分享给朋友:

相关文章

js实现吸色

js实现吸色

使用Canvas实现吸色功能 通过Canvas的getImageData方法获取像素颜色数据。创建一个Canvas元素,将目标图像绘制到Canvas上,通过鼠标事件获取坐标对应的颜色值。 const…

js实现跑马灯

js实现跑马灯

实现跑马灯效果 使用HTML和JavaScript可以轻松实现跑马灯效果。以下是两种常见的实现方式: HTML结构 <div id="marquee"> <span>…

js分页实现

js分页实现

分页的基本原理 分页的核心是通过计算当前页码和数据偏移量,从服务器或本地数据中截取对应范围的数据进行展示。通常需要以下参数:当前页码(currentPage)、每页条数(pageSize)、总数据量(…

实现继承js

实现继承js

实现继承的方式 在JavaScript中,实现继承可以通过多种方式完成,每种方式都有其优缺点。以下是几种常见的实现继承的方法: 原型链继承 原型链继承是最基本的继承方式,通过将子类的原型指向父类的实…

js实现弹框

js实现弹框

使用 alert 实现简单弹框 JavaScript 的 alert 方法可以直接显示一个简单的弹框,内容为纯文本: alert("这是一个简单的弹框"); 使用 confirm 实现确认弹框…

js实现音乐播放

js实现音乐播放

使用HTML5 Audio API实现音乐播放 在JavaScript中,可以通过HTML5的Audio API轻松实现音乐播放功能。以下是基本实现方法: // 创建Audio对象 const au…