【react18原理探究实践】组件的 props 和 state 究竟是如何确定和存储的?

🧑‍💻 前言

在上一篇文章里,我们从 scheduleUpdateOnFiber 出发,分析了 render 阶段的完整流程 :从 beginWork 递到 completeWork 归,最终构建 Fiber 树和 DOM。

那么,在这整个流程里,组件的 props 和 state 究竟是如何确定和存储的?


1. Props & State 在 Fiber 中的存储

先来看 Fiber 节点和 props/state 的关系:

js 复制代码
type Fiber = {
  pendingProps: any;   // 新的 props
  memoizedProps: any;  // 已确认的 props
  memoizedState: any;  // 已确认的 state
  updateQueue: any;    // 更新队列
  stateNode: any;      // 类实例 or DOM 节点
}

要点:

  • props :从父组件传入,先放到 pendingProps,在 performUnitOfWork 结束时赋值给 memoizedProps。

  • state:来源不同:

    • 类组件 → constructor(this.state)
    • 函数组件 → useState 初始化 Hook 链表
    • DOM 节点没有 state

2. Props 流程

来看 performUnitOfWork 的关键逻辑:

js 复制代码
function performUnitOfWork(unitOfWork) {
  const next = beginWork(unitOfWork.alternate, unitOfWork, renderLanes);

  // 🔥 在这里 props 生效
  unitOfWork.memoizedProps = unitOfWork.pendingProps;

  return next;
}
  • 每个 Fiber 在进入 beginWork 前,props 存在 pendingProps。
  • beginWork 执行完,pendingProps → memoizedProps。
  • 归阶段不再修改 props。

👉 所以:props 的确认时机在递阶段执行完毕时。


3. State 流程

3.1 类组件

js 复制代码
function updateClassComponent(current, workInProgress, Component, nextProps) {
  if (!workInProgress.stateNode) {
    // 🔥 构造实例并初始化 state
    const instance = new Component(nextProps);
    workInProgress.stateNode = instance;
    workInProgress.memoizedState = instance.state;
  }

  const nextChildren = workInProgress.stateNode.render();
  reconcileChildren(current, workInProgress, nextChildren, renderLanes);
}

特点:

  • new Component(props) 创建实例 → state 从 constructor 里拿。
  • fiber.memoizedState = instance.state。
  • 每次更新时,updateQueue 合并后的结果也会写到 memoizedState。

3.2 函数组件

js 复制代码
function updateFunctionComponent(current, workInProgress, Component, nextProps) {
  let nextChildren = renderWithHooks(current, workInProgress, Component, nextProps);
  reconcileChildren(current, workInProgress, nextChildren, renderLanes);
}

内部执行:

js 复制代码
function mountState(initialState) {
  const hook = mountWorkInProgressHook();
  hook.memoizedState = initialState;
  return [hook.memoizedState, dispatchSetState];
}

特点:

  • 首次挂载时,HooksDispatcherOnMount 生效。
  • useState(initial) → 创建 Hook 对象,挂到 Fiber.memoizedState 形成链表。
  • 后续更新时,Hook 链表会被复用。

3.3 DOM 节点

js 复制代码
function updateHostComponent(current, workInProgress, renderLanes) {
  const nextProps = workInProgress.pendingProps;
  // HostComponent 没有 state
  reconcileChildren(current, workInProgress, nextProps.children, renderLanes);
}

特点:

  • 只有 props,没有 state。
  • memoizedState 恒为 null。

4. Props & State 流程图

js 复制代码
父组件传入 props → Fiber.pendingProps
                ↓
beginWork 执行完毕
                ↓
Fiber.memoizedProps = pendingProps   // props 确认
                ↓
ClassComponent: memoizedState = instance.state
FunctionComponent: memoizedState = Hook 链表
HostComponent: 无 state

5. 小结对比

组件类型 Props 确认位置 State 初始化来源 Fiber 存储点
类组件 performUnitOfWork constructor(this.state) memoizedProps & memoizedState
函数组件 performUnitOfWork useState(initial) Hook memoizedProps & Hook 链表
DOM 组件 performUnitOfWork 无 memoizedProps,无 state

📌 总结

  • Props :统一流程,进入 beginWork 时在 pendingProps,出 beginWork 后确认到 memoizedProps。

  • State:来源依组件类型不同:

    • 类组件 → 构造函数初始化,存 Fiber.memoizedState
    • 函数组件 → useState 初始化 Hook 链表,存 Fiber.memoizedState
    • DOM 组件 → 无 state
  • 最终落点 :无论 props 还是 state,都会落到 Fiber 节点上。

一句话总结:

👉 首次挂载时,props 在递阶段确认,state 按组件类型初始化,统一写入 Fiber,供后续 render & commit 使用。

相关推荐
福兮说2 小时前
设计稿是 #4A7C6F,页面量出来是 #4B7C6F:HEX、HSL、透明度、canvas 来回转的七个坑
前端·javascript·css·canvas
郑州光合科技余经理3 小时前
海外版外卖加盟:总站与分站配送规则怎么分开管
java·开发语言·前端·后端·uni-app·php·ai编程
小呆呆6664 小时前
副业搞起来,小说,漫画,漫剧的成本优化思路
前端·后端·面试
Dovis(誓平步青云)4 小时前
浇水提醒刚弹出又消失,植物状态别只存一个百分比
开发语言·前端·javascript·pdf·ecmascript·电脑
码艺-Alimjan4 小时前
Vben Admin 新增维吾尔语 Vben-Modal的关键坑之一
前端·javascript·vue.js
可乐鸡翅yeah_5 小时前
hls.js 手动自定义 http 请求 loader,修改请求头实战
开发语言·前端·javascript·网络协议·http·ecmascript·m3u8在线
IT_陈寒5 小时前
Vite静态资源导入这个坑我帮你们踩过了
前端·人工智能·后端
广州华水科技5 小时前
大坝安全监测解决方案:单北斗GNSS形变监测系统应用与维护
前端
yivifu6 小时前
中文古籍电子书注释集成
前端·javascript·python·beautifulsoup·epub
默_笙7 小时前
🛴 从散件到整机:DeepAgents 与 Agent 身上预留的那些"插槽"(前置介绍)
前端·javascript