React学习-setState、useState

setState

语法:

kotlin 复制代码
this.setState(updater, [callback])

写法总结:

javascript 复制代码
// 语法:this.setState({ newState })
this.setState({ count: 1 });
​
// 推荐使用,尤其是状态更新依赖于前一次状态时。它可以接收当前 state 和 props
// 语法:this.setState((state, props) => { return { newState } })
this.setState((state, props) => ({
  count: state.count + 1
}));
​
// 在 setState 更新完成并重新渲染界面后执行,可确保获取到最新状态
this.setState({ count: 1 }, () => {
  console.log('更新后的状态:', this.state.count);
});

特性:

  • setState 是异步的 :React 会将多个 setState 调用合并(batch)成一次更新,以提升性能。
  • 事件处理函数 (如 onClick)中,setState 是批量的。
  • 原生事件、setTimeout、Promise 等异步上下文 中,setState 可能不会自动批处理(但在 React 18+ 中已改进),可能表现为`同步状态。

⚠️ 注意:React 18 开始,无论在哪里调用 setState,默认都会自动批处理(automatic batching)。

底层原理(React 16+ Fiber 架构)

  • 调用 setState 会触发 enqueueSetState
  • React 将更新放入一个更新队列(Update Queue) ,并标记该 Fiber 节点为"需要更新"。
  • 渲染阶段(render phase) ,React 会遍历 Fiber 树,收集所有待更新的节点。
  • 提交阶段(commit phase) ,应用 DOM 更新并触发副作用(如生命周期方法)。

关键点:setState 并不立即修改 this.state,而是创建一个更新对象(update object),由 React 调度器(Scheduler)决定何时处理。

useState

它允许你向组件添加一个 状态变量,语法:

scss 复制代码
const [state, setState] = useState(initialState)

它没有回调函数;

特性:

  • setState 一样,useStatesetXXX 也是异步且批量更新的。
  • React 18 后,在任何上下文中(包括 setTimeout)都会自动批处理。

底层原理(Hooks 机制)

  • useState 是 React Hooks 的一部分,其状态存储在 Fiber 节点的 memoizedState 字段中。

  • 每个 Hook(如 useState, useEffect)在 Fiber 节点上按调用顺序形成一个链表(Hook 链表)

  • 调用 setCount 时,React 会:

    1. 创建一个更新对象(类似类组件的 update)。
    2. 将其加入对应 Hook 的更新队列。
    3. 触发组件重新渲染(schedule update)。
  • 在下一次渲染时,React 会遍历 Hook 链表,应用所有 pending updates,计算出新的 state。

📌 关键:Hooks 的状态与组件实例绑定 ,通过 Fiber 节点维持状态,而不是像类组件那样通过 this.state

setState vs useState 对比

特性 setState(类组件) useState(函数组件)
状态结构 单个对象(可包含多个字段) 多个独立状态(每个 useState 管理一个)
更新方式 合并对象(shallow merge) 替换整个值(非合并)
初始值 构造函数中定义 useState(initialValue)
底层存储 this.state(实际由 Fiber 管理) Fiber 的 memoizedState 链表
性能 批量更新,Fiber 调度 同左,支持并发模式
推荐使用 已逐渐被函数组件取代 React 官方推荐方式

💡 注意:useState 不会自动合并对象!

底层共通机制(React 18+)

无论是 setState 还是 useState,最终都依赖于:

  1. Fiber 架构:每个组件对应一个 Fiber 节点,状态和更新都挂载其上。
  2. 更新队列(Update Queue) :存放待处理的状态变更。
  3. 调度器(Scheduler) :基于优先级(如用户交互高优先级)决定何时执行更新。
  4. 协调(Reconciliation) :通过 diff 算法生成最小 DOM 操作。
  5. 自动批处理(Automatic Batching) :React 18 起,所有状态更新默认批处理。
相关推荐
郭老二13 小时前
【前端】vue3:编译步骤
前端
不在逃避q14 小时前
Trae/Vs Code/Cursor命令行无法跑npm命令
前端·arcgis·npm
夏殇之殁14 小时前
包中创建自定义列表项。 . 使用自定义列表项进行数据绑定 . 将天气预报数据保存到本地内存表,通过LiveBindings进行显示。 ...
服务器·前端·javascript
The Chosen One98515 小时前
高进度算法模板速记(待完善)
java·前端·算法
陈随易15 小时前
MoonBit抓包模块pcap,查看电脑的每一次联网通信
前端·后端·程序员
新中地GIS开发老师16 小时前
WebGIS开发学生作品|低空航天管理与航线规划系统
前端·javascript·webgis·三维gis开发
用户0595401744616 小时前
大模型对话记忆持久化踩坑实录:用 Playwright 自动化测了 300 次,终于揪出会话丢失的真凶
前端·css
丙氨酸長鏈16 小时前
Web前端入门第 问:JavaScript 一个简单的 IndexedDB 数据库入门示例
前端·javascript·数据库
kyriewen17 小时前
面试官让我手写虚拟列表——AI生成的版本,快速滚动几下就白屏了
前端·javascript·面试
IT_陈寒17 小时前
Vite热更新失效?你可能漏了这个配置
前端·人工智能·后端