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

};

相关推荐
kyriewen10 小时前
Anthropic 估值逼近万亿美元,Claude Sonnet 5 + Claude Science 一天两连发
前端·ai编程·claude
小徐_233311 小时前
Wot UI 2.2.0 发布:Button 新增 subtle,VideoPreview 预览体验继续增强
前端·微信小程序·uni-app
天蓝色的鱼鱼13 小时前
关于 CSS 你可能不知道的属性,但关键时刻很有用
前端·css
泯泷14 小时前
第 2 篇:设计第一套字节码:Opcode、Instruction 与 Constant Pool
前端·javascript·安全
妙码生花14 小时前
从 PHP 到 AI + Golang,程序员自救转型手记(十五):优化细节、网络请求封装
前端·后端·ai编程
泯泷14 小时前
第 1 篇:从 1 + 2 开始:亲手写出第一台 JSVM
前端·javascript·安全
团团崽_七分甜14 小时前
Spring Boot 核心知识点总结
前端
lichenyang45315 小时前
从一个按钮开始,理解 ASCF 框架到底在做什么
前端
古夕15 小时前
第三方 SSO 接入实践:redirect_uri 编码、回调一致性与跨项目联调
前端·vue.js