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 一样,useState 的 setXXX 也是异步且批量更新的。
  • 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 起,所有状态更新默认批处理。
相关推荐
郑州光合科技余经理4 分钟前
海外版外卖加盟:总站与分站配送规则怎么分开管
java·开发语言·前端·后端·uni-app·php·ai编程
小呆呆66640 分钟前
副业搞起来,小说,漫画,漫剧的成本优化思路
前端·后端·面试
Dovis(誓平步青云)1 小时前
浇水提醒刚弹出又消失,植物状态别只存一个百分比
开发语言·前端·javascript·pdf·ecmascript·电脑
码艺-Alimjan2 小时前
Vben Admin 新增维吾尔语 Vben-Modal的关键坑之一
前端·javascript·vue.js
可乐鸡翅yeah_2 小时前
hls.js 手动自定义 http 请求 loader,修改请求头实战
开发语言·前端·javascript·网络协议·http·ecmascript·m3u8在线
IT_陈寒2 小时前
Vite静态资源导入这个坑我帮你们踩过了
前端·人工智能·后端
广州华水科技2 小时前
大坝安全监测解决方案:单北斗GNSS形变监测系统应用与维护
前端
yivifu3 小时前
中文古籍电子书注释集成
前端·javascript·python·beautifulsoup·epub
默_笙4 小时前
🛴 从散件到整机:DeepAgents 与 Agent 身上预留的那些"插槽"(前置介绍)
前端·javascript
zhangzeyuaaa4 小时前
深入理解 Ruby 运算符:本质、分类、坑点与重载实战
开发语言·前端·ruby