react源码解析14.手写hooks

react源码解析14.手写hooks

视频讲解(高效学习):进入学习

最关键的是要理解hook队列和update队列的指针指向和updateQueue的更新计算,详细见视频讲解

import React from "react";
import ReactDOM from "react-dom";

let workInProgressHook;//当前工作中的hook
let isMount = true;//是否时mount时

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

const Dispatcher = (() => {//Dispatcher对象
  function mountWorkInProgressHook() {//mount时调用
    const hook = {//构建hook
      queue: {//更新队列
        pending: null//未执行的update队列
      },
      memoizedState: null,//当前state
      next: null//下一个hook
    };
    if (!fiber.memoizedState) {
      fiber.memoizedState = hook;//第一个hook的话直接赋值给fiber.memoizedState
    } else {
      workInProgressHook.next = hook;//不是第一个的话就加在上一个hook的后面,形成链表
    }
    workInProgressHook = hook;//记录当前工作的hook
    return workInProgressHook;
  }
  function updateWorkInProgressHook() {//update时调用
    let curHook = workInProgressHook;
    workInProgressHook = workInProgressHook.next;//下一个hook
    return curHook;
  }
  function useState(initialState) {
    let hook;
    if (isMount) {
      hook = mountWorkInProgressHook();
      hook.memoizedState = initialState;//初始状态
    } else {
      hook = updateWorkInProgressHook();
    }

    let baseState = hook.memoizedState;//初始状态
    if (hook.queue.pending) {
      let firstUpdate = hook.queue.pending.next;//第一个update

      do {
        const action = firstUpdate.action;
        baseState = action(baseState);
        firstUpdate = firstUpdate.next;//循环update链表
      } while (firstUpdate !== hook.queue.pending);//通过update的action计算state

      hook.queue.pending = null;//重置update链表
    }
    hook.memoizedState = baseState;//赋值新的state

    return [baseState, dispatchAction.bind(null, hook.queue)];//useState的返回
  }

  return {
    useState
  };
})();

function dispatchAction(queue, action) {//触发更新
  const update = {//构建update
    action,
    next: null
  };
  if (queue.pending === null) {
    update.next = update;//update的环状链表
  } else {
    update.next = queue.pending.next;//新的update的next指向前一个update
    queue.pending.next = update;//前一个update的next指向新的update
  }
  queue.pending = update;//更新queue.pending

  isMount = false;//标志mount结束
  workInProgressHook = fiber.memoizedState;//更新workInProgressHook
  schedule();//调度更新
}

function App() {
  let [count, setCount] = Dispatcher.useState(1);
  let [age, setAge] = Dispatcher.useState(10);
  return (
    <>
      <p>Clicked {count} times</p>
      <button onClick={() => setCount(() => count + 1)}> Add count</button>
      <p>Age is {age}</p>
      <button onClick={() => setAge(() => age + 1)}> Add age</button>
    </>
  );
}

function schedule() {
  ReactDOM.render(<App />, document.querySelector("#root"));
}

schedule();
<think>嗯,用户之前问过关于全栈转Go和AI后端的学习计划,现在他进一步说明了自己的情况。他现在是大一学生,想要先在学校里学好全栈,积累经验后再转向后端专精,特别是从Node.js转到Go。我需要根据他的新需求调整学习计划。 首先,回顾之前的计划,我给他制定了一个分阶段的计划,从全栈基础到Go后端再到AI集成。但现在用户明确说想先专注全栈,之后再转后端。因此,重点应该放在全栈基础,特别是Node.js,然后逐步过渡到Go。 接下来,我需要确定用户的需求是否有变化。用户之前的目标是Go+AI业务后端,但现在更倾向于先全栈再转后端。可能用户意识到全栈基础对后端开发有帮助,或者对Node.js更熟悉,想先打好基础再转语言。需要确保新计划既涵盖全栈技能,又为后续转向Go做准备。 然后,制定阶段性的计划。第一阶段应该巩固前端基础,包括HTML、CSS、JavaScript,然后是前端框架如Vue或React。同时,后端部分先用Node.js,学习Express或Koa框架,数据库使用MongoDB或MySQL。项目实战需要整合前后端,部署到云服务器。 第二阶段,深化后端能力,逐步引入Go语言。这时候用户已经有Node.js经验,对比学习Go会更高效。需要设计项目,让用户用Go重构部分Node.js的后端,体验两者差异。同时,学习分布式系统和微服务,为进阶做准备。 第三阶段,转向后端专精,特别是Go的高并发和云原生技术。项目方面需要更复杂的系统,如高并发应用或微服务架构,并集成监控和日志系统。同时,结合之前的全栈经验,可能涉及CI/CD和容器化部署。 另外,要注意用户可能的时间安排,作为大学生,课程和项目需要平衡。建议利用寒暑假集中学习,学期中巩固知识。同时,参与开源项目和撰写技术博客可以提升竞争力。 最后,避免之前的误区,比如过早追求新技术,应专注当前技术栈,打好基础。同时,强调项目实践和代码质量,确保每个阶段都有可展示的成果,帮助校招时脱颖而出。 总结,调整后的计划应分三阶段:全栈基础(Node.js)、后端过渡(Go引入)、后端专精(Go深度)。每个阶段都有明确的学习内容和项目,确保用户逐步提升,平滑过渡到后端开发,同时保持全栈的广度。</think>--- ### **全栈→后端专精(Node.js→Go)学习计划** **核心逻辑**:**“全栈广度建立工程认知 → 逐步下沉后端技术深度”**,用Node.js快速实现业务闭环,后期迁移到Go提升性能 --- #### **阶段1:大一暑假-大二上(全栈基础)** **目标**:**用Node.js+React实现可商用的Web应用** | 时间 | 学习模块 | 关键内容 | 验证标准 | |---|---|---|---| | **第1-2周** | **现代前端基础** | - TypeScript类型系统<br>- React Hooks状态管理<br>- Tailwind CSS原子化样式 | 实现知乎风格问答页面 | | **第3-4周** | **Node.js核心** | - Express中间件机制<br>- RESTful API设计规范<br>- JWT鉴权流程 | 开发博客系统API(带RBAC权限) | | **第5-6周** | **数据库实战** | - MongoDB聚合管道<br>- Mongoose模式验证<br>- Redis缓存热点数据 | 构建商品秒杀系统(防超卖) | | **第7-8周** | **工程化基建** | - Webpack配置优化<br>- Docker容器化部署<br>- GitHub Actions自动化 | 实现CI/CD全流程(Dev→Prod) | | **第9-12周** | **全栈项目** | - Next.js服务端渲染<br>- Node.js对接支付接口(支付宝沙箱)<br>- 性能监控(Sentry) | 上线校园二手交易平台 | **实战技巧**: - 使用`swagger-ui-express`自动生成API文档 - 在Vercel免费托管Next.js应用(体验Serverless) --- #### **阶段2:大二下-大三上(后端深化)** **目标**:**将Node.js项目逐步迁移到Go,建立性能对比认知** ##### **迁移策略** ``` Node.js服务 → Go重写关键模块 → 混合架构 │ │ ├─ 保留快速迭代优势 └─ 用Go处理高并发场景(如WebSocket推送) ``` ##### **学习路线** 1. **Go语言特性**: - 对比Node.js事件循环与Go协程调度(画Goroutine生命周期图) - 用`go test -bench`对比Fibonacci函数的性能差异 2. **渐进迁移案例**: - **案例1**:用户服务迁移 - 原Node.js代码:Express + Mongoose - Go重写方案:Gin + GORM + JWT-go - **案例2**:实时聊天模块 - 原Node.js方案:Socket.io + Redis Pub/Sub - Go优化方案:Gorilla WebSocket + NSQ消息队列 3. **性能调优**: - 用`pprof`分析Go程序内存泄漏 - 使用`vegeta`对Node.js/Go接口做压力测试对比 --- #### **阶段3:大三下-大四(后端专精)** **目标**:**构建Go领域模型设计能力,冲击基础设施层开发** ##### **高阶技术栈** | 领域 | 关键技术 | 学习方式 | |---|---|---| | **并发模型** | - Goroutine泄漏检测<br>- sync.Pool对象池<br>- atomic无锁编程 | 阅读《Concurrency in Go》并手写线程安全队列 | | **分布式系统** | - Raft共识算法实现<br>- 分布式锁(etcd)<br>- 分布式追踪(OpenTelemetry) | 实现简易版Redis Cluster | | **云原生** | - Operator模式开发<br>- Service Mesh数据面代理<br>- 可观测性体系构建 | 用Go重写Envoy过滤器 | ##### **差异化项目建议** 1. **数据库中间件开发** - 实现SQL防火墙(解析AST拦截危险操作) - 开发分库分表路由组件(基于一致性哈希) 2. **AI基础设施** - 用Go实现模型服务化(ONNX Runtime CGO绑定) - 构建特征计算引擎(替代Python Pandas) --- #### **关键转折点训练** 1. **思维转换训练**: - 每周用Go重写一个Node.js模块(如文件上传服务) - 在LeetCode用Go刷题(重点:并发题、系统设计题) 2. **架构视野提升**: - 研究CNCF项目架构图(如Kubernetes Scheduler) - 用PlantUML绘制自己项目的分层架构 --- ### **校招突围策略** $$ \text{Offer概率} = \frac{ \text{全栈项目} \times \text{性能优化经验} }{ \text{八股文盲区} } + \text{基础架构理解} $$ **执行要点**: - 在简历中明确标注**性能提升数据**(如“Go重写后QPS从800提升至5200”) - 准备《Node.js到Go的架构迁移思考》技术文章作为加分项 --- ### **学习资源精准推荐** 1. **Node.js深度**: - 书籍:《Node.js设计模式(第2版)》(重点第6章流处理) - 视频:Udemy《Advanced Node.js for Developers》 2. **Go进阶**: - 开源项目:etcd源码(学习Raft实现) - 专栏:极客时间《Go 语言从入门到实战》 --- 通过这种路径,你将在保留全栈快速开发能力的同时,逐步在后端领域建立**不可替代的技术纵深**。大四时可选择: - **路径1**:加入使用Go的中厂(如B站/七牛云) - **路径2**:进入AI基础设施初创公司(需补充K8s生态知识)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值