React中Store的Impacts getter方法被多次调用的原因是什么?
问题原因
原生JavaScript的getter本身不具备结果缓存能力,每次访问this.Impacts都会完整执行getter内的全部逻辑。你当前场景下一共3次访问(组件直接访问1次、getImpactedTenants调用1次、overallMonthlyImpactedTenants调用1次),所以会触发3次执行,和你观测到的现象一致。
解决方案
根据你使用的Store实现方式选择对应方案即可:
方案1:基于MobX等带计算缓存能力的状态管理库
如果你用的是MobX,只需要给Impacts getter加上@computed装饰器即可。MobX会自动跟踪依赖的this.rawMonthlyImpacts变化,依赖未更新时会直接返回缓存结果,不会重复执行计算逻辑。
方案2:手动实现缓存逻辑
如果是自研Store,自己加缓存和缓存失效逻辑即可,参考代码如下:
// Store内新增私有缓存变量和有效标记 #cachedImpacts: Map<string, Map<string, number>> | null = null; #isImpactsCacheValid = false; // 你请求后端API更新rawMonthlyImpacts的位置,新增缓存失效逻辑 this.rawMonthlyImpacts = await fetchImpactsApi(); this.#isImpactsCacheValid = false; // 依赖更新后标记缓存失效 get Impacts(){ // 缓存有效时直接返回结果 if (this.#isImpactsCacheValid && this.#cachedImpacts) { return this.#cachedImpacts; } const monthlyImpacts = new Map<string, Map<string, number>>(); if (this.rawMonthlyImpacts) { this.rawMonthlyImpacts.forEach((impact) => { if (impact.Impact > 0) { const month = TimeConversion.fromTimestampToMonthString(impact.Month); const tenantId = impact.TenantId; const tenantImpact = impact.Impact; if (!monthlyImpacts.has(month)) { const tenantList = new Map<string, number>(); tenantList.set(tenantId, tenantImpact); monthlyImpacts.set(month, tenantList); } else { const tenantWithImpactMap = monthlyImpacts.get(month)!; const existing = tenantWithImpactMap.get(tenantId) ?? 0; tenantWithImpactMap.set(tenantId, existing + tenantImpact); } } }); } // 更新缓存并标记有效 this.#cachedImpacts = monthlyImpacts; this.#isImpactsCacheValid = true; return monthlyImpacts; }
额外优化建议
如果getImpactedTenants和overallMonthlyImpactedTenants也会被多次调用,也可以参照上述逻辑给这两个方法也加上缓存,进一步减少不必要的计算。
内容的提问来源于stack exchange,提问作者wei wang
相关产品推荐
相关产品推荐

