HOOKS 背后机制

js 复制代码
function UserProfile() {  
  // Hook 1: useState  
  const [name, setName] = useState('John');  
    
  // Hook 2: useEffect    
  useEffect(() => {  
    document.title = `用户: ${name}`;  
  }, [name]);  
    
  // Hook 3: useMemo  
  const displayName = useMemo(() => {  
    return name.toUpperCase();  
  }, [name]);  
    
  return <h1>{displayName}</h1>;  
}

React 内部会这样组织数据:

    1. Fiber 节点 :代表 UserProfile 组件
    1. Hook 链表useStateuseEffectuseMemo → null
    1. 状态管理useState 的 Hook 对象包含当前值 'John' 和更新队列
    1. 副作用管理useEffect 的 Effect 对象存储在 Fiber 的副作用队列中
js 复制代码
// 基于 ReactFiberHooks.js 源代码的 Hook 类型定义  
export type Hook = {  
  memoizedState: any,                    // 💾 存储当前 hook 的状态值或缓存值  
  baseState: any,                        // 🎯 用于计算下一次 state 的基础 state  
  baseQueue: Update<any, any> | null,    // 🔄 存储跳过的低优先级 update  
  queue: any,                            // 📋 指向 UpdateQueue 对象,存储待处理的 update  
  next: Hook | null,                     // ➡️ 指向下一个 Hook 对象的指针  
};
js 复制代码
function UserProfile() {  
  const [name, setName] = useState('John');     // Hook 1  
  const [age, setAge] = useState(25);           // Hook 2  
    
  useEffect(() => {                             // Hook 3  
    console.log(`${name} is ${age} years old`);  
  }, [name, age]);  
    
  return <div>{name} ({age})</div>;  
}
js 复制代码
// Fiber.memoizedState 指向的 Hook 链表  
const hookChain = {  
  // Hook 1: useState(name)  
  memoizedState: 'John',           // 💾 当前 name 的值  
  baseState: 'John',               // 🎯 基础状态  
  queue: {                         // 📋 UpdateQueue 对象  
    pending: null,                 // 当前没有待处理的更新  
    dispatch: setName,             // setState 函数  
    lastRenderedState: 'John'  
  },  
  baseQueue: null,                 // 🔄 没有跳过的更新  
  next: {                          // ➡️ 指向下一个 Hook  
      
    // Hook 2: useState(age)  
    memoizedState: 25,             // 💾 当前 age 的值  
    baseState: 25,                 // 🎯 基础状态  
    queue: {  
      pending: null,  
      dispatch: setAge,  
      lastRenderedState: 25  
    },  
    baseQueue: null,  
    next: {  
        
      // Hook 3: useEffect  
      memoizedState: {             // 💾 Effect 对象  
        tag: 'Passive',            // useEffect 的标记  
        create: () => console.log(`${name} is ${age} years old`),  
        deps: ['John', 25],        // 依赖数组的当前值  
        destroy: undefined         // 清理函数(如果有的话)  
      },  
      queue: null,               // useEffect 没有更新队列  
      baseQueue: null,  
      next: null                 // 🔚 链表结束  
    }  
  }  
};

setName('Jane') 时,React 并不会立即更新状态,而是创建一个 "更新任务" 并放入队列中。这就是 UpdateQueue

// UpdateQueue 类型定义

export type UpdateQueue<S, A> = {

pending: Update<S, A> | null, // 📋 指向待处理更新的环形链表

lanes: Lanes, // 🚦 优先级标记

dispatch: (A => mixed) | null, // 🎯 setState 函数本身

lastRenderedReducer: ((S, A) => S) | null, // 🔄 上次使用的 reducer

lastRenderedState: S | null, // 💾 上次渲染的状态

};

// Update 对象类型定义

export type Update<S, A> = {

lane: Lane, // 🚦 本次更新的优先级

revertLane: Lane, // ↩️ 回滚优先级 (React 19 新增)

action: A, // 🎬 更新动作:值或函数

hasEagerState: boolean, // ⚡ 是否有预计算状态

eagerState: S | null, // 💡 预计算的状态值

next: Update<S, A>, // ➡️ 下一个更新(环形链表)

};

相关推荐
kyriewen41 分钟前
我把今年流传的前端 AI 面试题整理了一遍——4 类场景题+回答框架(附速查表)
前端·面试·程序员
计算机魔术师1 小时前
国产多模态模型正面硬刚Opus旗舰:差距从30%缩到3%
前端
风骏时光牛马1 小时前
程序员进阶:深度思考,解锁职场成长的底层逻辑
前端
IT_陈寒2 小时前
用了Proxy才发现以前的JavaScript白写了
前端·人工智能·后端
爱丶不疚2 小时前
Eval: Agent 说的 Eval 是什么?从单测、TDD 到 Sentry 聊起
前端·ai编程·vibecoding
求道於盲2 小时前
python中的类型标注
前端
计算机魔术师2 小时前
从硅谷测试到全球铺开,ChatGPT广告的10亿美元秘密
前端
专业抄代码选手3 小时前
08|Fiber 上的 `useState`:状态终于属于具体组件
前端·javascript·react.js
默_笙3 小时前
😭 Vibe Coding 翻车实录:AI 编程为什么必须先写"剧本"
前端·javascript
LEE3 小时前
原来 Claude Code 最厉害的工具,一行代码都不写
前端·后端