React Native 购物车总价总慢一拍?删掉多余的派生状态
·
专题:Hooks 与状态

购物车数量已经加一,总价却下一次渲染才跟上。页面同时保存 items 和 total,再用 Effect 监听 items 更新 total,看起来职责分明,实际上维护了两份本可直接计算的信息。
先理解问题
只要一个值能由当前输入确定,就先把它视为派生值。多保存一份状态,就多出同步时机、遗漏依赖和中间不一致的风险。总价计算很小的时候,直接计算比增加缓存和同步 Effect 更清楚。
实现路径
- 列出总价真正依赖的输入:数量、以最小货币单位表示的单价,以及已明确的优惠规则。
- 在渲染过程中运行纯计算函数,去掉负责同步 total 的 Effect。
- 只有测量表明计算明显昂贵时才缓存;先保持不可变更新,让缓存依赖能正确失效。
核心示例
type Line = {id: string; unitCents: number; quantity: number};
export function subtotal(lines: readonly Line[]): number {
return lines.reduce((sum, line) => {
if (!Number.isSafeInteger(line.unitCents) ||
!Number.isSafeInteger(line.quantity) || line.quantity < 0) {
throw new Error('Invalid cart line');
}
return sum + line.unitCents * line.quantity;
}, 0);
}
函数不修改购物车,也不负责展示货币符号。页面渲染时调用 subtotal(items),数量与小计来自同一份输入快照。示例仅表达普通小规模购物车的小计;超大金额仍需安全整数范围校验或专门十进制方案。
容易忽略的边界
服务端结算金额、优惠审核状态不一定是本地可推导值,不能一并删除。尤其是库存、税费与促销最终结果,要清楚标出“本地预估”和“服务端确认”,避免客户端计算变成交易事实。
怎么验证
- 连续增减数量:数量与小计在同一次可见更新中保持一致。
- 移除最后一条记录:总价回到 0,不保留旧值。
- 输入相同购物车两次:函数返回相同结果,原数组保持不变。
减少状态数量是降低复杂度的一种直接方式。每保留一份状态,都应能说明它为什么不能从其他状态得到。
适用范围与参考
示例用于说明设计与排查方法,非完整应用,也不代表已经过设备实测。 组件片段需接入对应项目;文中自定义函数、示意协议和策略数值需按业务补齐。迁移到 OHOS 时应另外核对适配层支持。
更多推荐


所有评论(0)