当前位置:首页 > JavaScript

js实现reacthooks

2026-02-01 14:28:52JavaScript

js实现reacthooks

实现 React Hooks 的 JavaScript 核心逻辑

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

基础 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 文件。

js实现reacthooks

标签: jsreacthooks
分享给朋友:

相关文章

js实现轮播

js实现轮播

实现基础轮播效果 使用HTML结构创建轮播容器和图片元素: <div class="carousel"> <div class="carousel-inner">…

js实现倒计时

js实现倒计时

实现倒计时的基本方法 使用 JavaScript 实现倒计时功能可以通过 setInterval 或 setTimeout 结合日期计算来完成。以下是几种常见的实现方式: 使用 setInterv…

vue.js实现轮播

vue.js实现轮播

Vue.js 实现轮播功能 使用第三方库(推荐) Vue.js 生态中有许多成熟的轮播组件库,例如 vue-awesome-swiper 或 swiper,它们功能丰富且易于集成。 安装 swipe…

js实现轮播

js实现轮播

实现轮播图的基本思路 轮播图的核心逻辑是通过定时切换展示的图片或内容,通常结合左右滑动按钮和指示器(小圆点)增强交互性。以下是基于原生JavaScript的实现方法。 HTML结构 构建轮播图的H…

js实现验证码

js实现验证码

使用Canvas生成图形验证码 在HTML中创建一个Canvas元素用于绘制验证码。通过JavaScript随机生成数字或字母组合,并添加干扰线、噪点等干扰元素增强安全性。 <canvas…

js 进度条的实现

js 进度条的实现

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