Skip to content
前端工程与框架实践 · 第 3 篇 / 共 4 篇
领域编程与框架
专题前端工程专题
当前序列前端工程与框架实践
阅读位置第 3 篇 / 共 4 篇当前专题第 2 个序列 / 共 3 个序列

React 渲染流程和状态设计怎么做更稳

先说结论

  • React 渲染问题很多时候不是“渲染太多”,而是状态放错了位置
  • 本地状态、派生状态、服务端状态最好分开思考
  • 真正稳定的前端状态设计,重点不在技巧,而在边界清不清楚

一、先看渲染是怎么被触发的

一个组件重新渲染,常见原因通常只有几类:

  • 自己的 state 变了
  • 父组件重新渲染了
  • context 变化了
  • 外部状态订阅变了

所以很多“为什么又渲染了”的问题,本质上不是 React 神秘,而是某个上游状态变化已经把它带起来了。

二、状态最容易乱在哪里

前端项目里,最常见的混乱不是状态太少,而是不同性质的状态混在一起:

1. 本地交互状态

比如:

  • 弹窗开关
  • tab 选中项
  • 表单输入中间值

2. 服务端数据状态

比如:

  • 用户信息
  • 列表数据
  • 搜索结果

3. 派生状态

比如:

  • 根据列表筛选出的结果
  • 根据多个字段拼出来的展示文案

如果这三类状态都手动存一份,很快就会同步困难。

三、更稳的设计方式

1. 能派生的就别重复存

如果一个值能通过已有 state 计算出来,就尽量不要再维护第二份。

2. 状态尽量放在真正需要它的最低层

不是所有状态都要提到全局或页面顶层。
越往上放,带来的联动渲染通常越大。

3. 服务端数据和 UI 状态分开

查询结果、缓存、加载状态这类更适合交给专门的数据层管理;弹窗、输入框、选中态更适合本地管理。

四、最容易踩的坑

1. 一个页面顶层 state 管所有东西

这样一改一个小按钮,整页都可能跟着重新跑一遍。

2. 派生状态也手动维护

比如筛选结果、计数结果、格式化文案都单独存,最后很容易不同步。

3. 为了“优化渲染”过早做复杂拆分

很多时候真正的问题不是少了 memo,而是状态边界本来就没设计好。

总结

React 渲染流程本身并不神秘,关键在于状态怎么放。只要把本地状态、服务端状态和派生状态分开,尽量减少重复存储,很多渲染抖动和维护混乱问题都会自然收敛。

延伸阅读相关文章优先当前专题,再补跨专题关联。
同一序列 · 顺着当前主线继续读Webpack 和 Vite 的构建链路有什么区别适合把 TypeScript、框架响应式和构建流程放在同一条工程主线上看。前端工程专题 · 前端工程与框架实践同一序列 · 回看前文会更完整Vue 响应式和渲染更新怎么理解适合把 TypeScript、框架响应式和构建流程放在同一条工程主线上看。前端工程专题 · 前端工程与框架实践同专题其他序列 · 共享标签:Flink、前端React 列表渲染和 key 选择为什么会影响状态适合把缓存、类型系统、渲染机制和构建提效放在一条前端工程主线上看。前端工程专题 · 前端工程体验与性能判断同专题其他序列 · 共享标签:前端浏览器缓存、Cookie、LocalStorage、SessionStorage 怎么分工适合把事件循环、缓存、渲染和浏览器存储放到一起系统理解。前端工程专题 · 浏览器基础与前端运行机制跨专题关联 · 同场景:基础学习消费重试状态机到底怎么走适合把顺序消息、事务消息、消费重试和索引设计放在一条 RocketMQ 业务主线上看。RocketMQ 专题 · RocketMQ 业务语义与恢复治理跨专题关联 · 同场景:基础学习Bitmap 做签到和状态标记有什么边界适合把结构选型、统计场景、地理位置和流水消息放在一条 Redis 使用主线上判断。Redis 专题 · Redis 数据结构与命令使用边界
继续阅读前端工程与框架实践当前序列第 3 篇 / 共 4 篇当前专题第 2 个序列 / 共 3 个序列
往前看
上一篇Vue 响应式和渲染更新怎么理解回到当前序列上一章上一序列浏览器基础与前端运行机制从第 1 篇开始:JavaScript 事件循环和微任务怎么理解
往后看
下一篇Webpack 和 Vite 的构建链路有什么区别继续当前序列下一章下一序列前端工程体验与性能判断从第 1 篇开始:浏览器缓存协商和强缓存怎么配合

把零散经验整理成可查、可复用、可持续更新的企业级知识门户