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>, // ➡️ 下一个更新(环形链表)

};

相关推荐
码语智行1 小时前
首页导航跳转功能深度解析-系统内和系统外
前端
阿猫的故乡2 小时前
Vue过渡动画从入门到装X:淡入淡出、滑动、列表动画、第三方库全搞定
前端·javascript·vue.js
IManiy2 小时前
总结之Vibe Coding前端骨架
前端
JS菌2 小时前
AI Agent 沙箱双层防护体系:从权限过滤到内核隔离的完整实现
前端·人工智能·后端
Aphasia3112 小时前
从输入URL到页面展示全流程
前端·面试
我叫黑大帅3 小时前
前端如何竖屏固定视口背景
前端·javascript·面试
abcy0712133 小时前
python pandas csv异步后台清洗前端优先返回成功信息
前端·python·pandas
IT_陈寒3 小时前
Vite这个坑我帮你踩了,动态导入居然这样才生效
前端·人工智能·后端
swipe3 小时前
Mem0 x Agent 实战系列:分层记忆 + 三路召回,搭建真正可用的长期记忆层
前端·javascript·面试