当前位置: 首页 > news >正文

为什么“状态越集中”,RN 项目反而越卡

@[toc]

如果你做过一段时间 RN,大概率经历过下面这个过程:

  1. 一开始:useState写得很舒服
  2. 状态多了:开始集中管理
  3. Redux / Context / Store 上了
  4. 列表开始卡、动画掉帧
  5. 开始疯狂memouseCallback
  6. 发现——没救

很多人会把锅甩给 FlatList,但其实FlatList 只是把问题放大了

真正的问题是:
状态集中之后,渲染传播半径失控了。

先说结论:状态集中,本质是“广播”

我们先把话说透。

所谓“集中状态”,意味着什么?

  • 一个 state
  • 被很多组件依赖
  • 任意一个字段变化
  • 都会向所有订阅者发信号

一句话总结:

集中状态 = 广播式更新

而 RN 里,列表、动画、手势,全部都怕广播

一个你肯定写过的“合理结构”

我们从一个非常常见、非常“规范”的写法开始。

场景

一个列表,每一项可以点赞。

全局状态(Redux / Context / Store 都一样)

{likedMap:{'1':true,'2':false,'3':true,...}}

列表组件

function List() { const likedMap = useSelector(state => state.likedMap) return ( <FlatList data={data} renderItem={({ item }) => ( <Item item={item} liked={likedMap[item.id]} /> )} /> ) }

逻辑完全正确,对吧?

一次点赞,引发了什么?

我们不讲抽象概念,直接走一遍执行链路

当你点了一个 item 的点赞:

  1. dispatch(toggleLike(id))
  2. likedMap生成新对象
  3. useSelector命中
  4. List组件 re-render
  5. FlatList重新执行renderItem
  6. 所有Item重新参与 diff

注意一个细节:

不是 Item 自己 re-render,
而是整个列表重新走了一遍 render 流程。

为什么 memo / useCallback 救不了你?

你可能会说:

“我 Item memo 了啊”

const Item = React.memo(...)

但问题是:

  • 父组件已经 re-render
  • renderItem 已重新执行
  • props 已重新计算

memo 只能挡住最后一层组件执行
挡不住前面的 render 传播

这在 Web 项目里为什么没这么明显?

这是很多人误判的根源。

Web 有三层“兜底”

  1. 浏览器 DOM diff 极其成熟
  2. 合成层可以跳过大量重排
  3. 掉一两帧用户感知不强

RN 没有

  • render 就是 JS 执行
  • JS 卡,动画立刻掉
  • 列表一滚,问题全部暴露

所以 RN 会逼你面对一个现实:

你到底让多少组件,参与了这次状态更新?

Demo:全局状态 vs 局部状态

我们用一个最小 Demo 看差异。

错误示例:全局状态控制 item 点赞

function Page() { const [likedMap, setLikedMap] = useState({}) return ( <FlatList data={list} renderItem={({ item }) => ( <Item item={item} liked={likedMap[item.id]} onLike={() => setLikedMap(prev => ({ ...prev, [item.id]: !prev[item.id] })) } /> )} /> ) }

问题点:

  • 任意一次点赞
  • Page re-render
  • FlatList re-render
  • 全部 item 被波及

正确示例:局部状态下沉到 Item

function Item({ item }) { const [liked, setLiked] = useState(false) return ( <Pressable onPress={() => setLiked(v => !v)}> <Text>{liked ? '❤️' : '🤍'}</Text> </Pressable> ) }

现在变化变成:

  • 只有一个 Item
  • 一个 state
  • 一个 re-render

那 Redux / Zustand / Context 该怎么用?

重点不是“用不用”,而是用在什么层级

Redux:不适合什么?

不适合:

  • 点赞
  • 勾选
  • 展开
  • hover / focus
  • 高频 UI 交互

这些状态有一个共同点:

变化频率高,但影响范围极小

Redux 适合什么?

  • 列表数据本身
  • 分页 / 筛选条件
  • 用户信息
  • 权限、配置

一句话:

改了就应该影响整个页面的状态,才配放 Redux。

Zustand 的优势在哪?

const liked = useStore(state => state.likedMap[id])

这里真正关键的是:

selector 是订阅边界

  • store 变没关系
  • selector 没变就不 re-render

所以 Zustand 在 RN 列表里天然更顺手

Context:隐形杀手

<Context.Provider value={{ likedMap }}>

只要 value 是新对象:

所有 useContext 的组件,全部重绘

这也是为什么 Context 在列表里最容易“悄悄拖死性能”。

状态粒度拆分的实用规则

给你一套非常好用的判断标准。

你在决定“这个状态放哪”时,只问 3 个问题:

  1. 它变化频率高吗?
  2. 它影响多少个 item?
  3. 改它,是否“业务上就该全刷”?

判断结果:

状态类型推荐位置
列表数据Redux / Query
筛选条件页面 state
点赞 / 展开Item 本地
动画进度sharedValue

为什么“状态集中”在 RN 是反模式?

不是集中本身错,而是集中得太早、太粗

在 RN 里更合理的哲学是:

结构集中,交互分散。

  • 页面结构:集中管理
  • Item 行为:就地消化

总结

如果你只记住一句:

RN 项目不是“状态越集中越好”,
而是**“状态传播半径越小越安全”**。

FlatList 不背锅,
状态模型才是性能的第一责任人。

http://www.jsqmd.com/news/186468/

相关文章:

  • 为什么状态一集中,所有 RN 性能优化都会失效
  • AI开发工具----碾压 Bolt.new?Lovable:全栈开发的下一个“卷王”级神器深度评测
  • 揭秘Java应用性能拐点预测:如何用机器学习构建高精度运维模型
  • GitHub 热榜----86k+ Star!Awesome-LLM-Apps:可能是全网最好的 LLM 应用开发“实战圣经”
  • Elastic Stack梳理:深度解析Elasticsearch分布式查询机制与相关性算分优化实践 - 教程
  • 提升AI生成一致性:用lora-scripts定制固定输出格式的LLM模型
  • 假期网络钓鱼攻击中DocuSign伪装与虚假贷款诈骗的融合机制分析
  • JLink驱动固件升级步骤图解说明
  • 巴厘岛目的地婚礼推荐:唯一时光专做目的地婚礼的国内领先品牌深度解析——三亚目的地婚礼推荐/丽江目的地婚礼推荐/新疆目的地婚礼推荐/大理目的地婚礼推荐 - charlieruizvin
  • 网盘直链下载助手提速lora-scripts模型权重下载全过程
  • 计算机毕设java校园二手物品交易平台 基于Java的校园二手交易系统开发与实现 Java技术驱动的校园二手物品交易管理平台设计
  • 工业级打印系统中32位驱动主机的操作指南
  • android openCV 应用 (四)图像处理中的多尺度分析 - 指南
  • 计算机毕设java校园快递管理平台 基于Java的校园快递信息管理系统开发 Java技术驱动的校园快递管理平台设计与实现
  • 飞书多维表格管理lora-scripts项目进度与任务分配
  • 清华镜像源加速lora-scripts项目依赖库安装,告别下载超时
  • 【JavaDoc Markdown预览终极指南】:掌握高效文档编写的5大核心技巧
  • STM32CubeMX教程中的PWM生成配置通俗解释
  • STM32MP1双核配置实战案例:从零实现系统启动
  • 单片机驱动蜂鸣器:零基础实战操作指南
  • 1411.给 N x 3 网格图涂色的方案数
  • 自动标注+手动修正双模式:lora-scripts高效构建metadata.csv文件
  • 一点资讯个性化推送:根据用户画像发送lora-scripts资讯
  • 国产算力卡如寒武纪、昇腾能否运行lora-scripts?
  • 飞算JavaAI配置生成避坑指南,99%新手都会忽略的关键细节
  • 快速上手ARM Cortex-M ISR配置:新手入门步骤
  • 为什么你的 Spring Native 应用启动要3秒?这5个关键优化点你必须掌握
  • 国内用户福音:huggingface镜像网站助力lora-scripts模型拉取
  • STM32中CANFD和CAN的区别:一文说清通信机制差异
  • 2026年GEO服务商全景解析(2026年1月更新) - 品牌2025