React useEffect更新state后部分关联数据未同步更新问题
问题根因
useState的初始值仅在组件首次挂载时生效1次,后续重渲染过程中不会自动重新读取传入的初始值更新状态。- 代码里的
maximum/minimum是组件渲染阶段直接计算的普通常量,每次PBTot更新触发重渲染时,都会基于最新状态值重新计算,所以能拿到正确结果。 - 而
Pvente/ChargesF是独立的状态:首次挂载时PBTot为初始值0,计算得到全0数组作为两个状态的初始值;后续接口返回更新PBTot触发重渲染时,没有主动调用setPvente/setChargesF同步新计算的默认场景值,两个状态会一直保留首次挂载时的全0数组,直到手动点击按钮触发set操作才会更新为当前渲染周期的最新计算值。
修复方案
优先选择第一种方案,从根源避免多状态同步问题:
方案1:移除冗余状态,直接用派生值渲染
不需要把当前展示的销售、费用数组存在state里,只需要存当前激活的场景标识,所有展示数据在每次渲染时基于最新PBTot派生即可,完全不需要手动做状态同步:
// 仅存当前选中的场景标识,默认是均值场景 const [activeScene, setActiveScene] = useState('moy') // 每次渲染自动基于最新PBTot计算所有派生值 const ChargesTot = PBTot * 0.85 // 计算5组波动场景的销售、费用数组 const ventesGroups = { veryLow: /* 基于PBTot计算的-20%波动数组 */, low: /* 基于PBTot计算的-10%波动数组 */, moy: /* 基于PBTot计算的默认均值数组 */, high: /* 基于PBTot计算的+10%波动数组 */, veryHigh: /* 基于PBTot计算的+20%波动数组 */ } const chargesGroups = { veryLow: /* 基于ChargesTot计算的-20%波动数组 */, low: /* 基于ChargesTot计算的-10%波动数组 */, moy: /* 基于ChargesTot计算的默认均值数组 */, high: /* 基于ChargesTot计算的+10%波动数组 */, veryHigh: /* 基于ChargesTot计算的+20%波动数组 */ } // 直接派生当前要传给子组件的展示值,永远和最新PBTot保持同步 const currentVentes = ventesGroups[activeScene] const currentCharges = chargesGroups[activeScene] // 计算最大最小值也直接基于全量数据计算即可 const maximum = /* 基于ventesGroups、chargesGroups计算最大值 */ const minimum = /* 基于ventesGroups、chargesGroups计算最小值 */ // 按钮点击只需要切换场景标识 <button onClick={() => setActiveScene('moy')}>Moy</button>
方案2:增加状态同步逻辑(不推荐,容易漏依赖出bug)
如果要保留原有Pvente/ChargesF的状态写法,需要新增监听PBTot的副作用,在PBTot更新后主动把新计算的默认场景值同步到对应状态中:
useEffect(() => { const ChargesTot = PBTot * 0.85 // 计算默认场景的最新数组 const newVentesMoy = /* 基于最新PBTot计算的默认销售数组 */ const newChargesMoy = /* 基于最新ChargesTot计算的默认费用数组 */ // 同步更新状态 setPvente(newVentesMoy) setChargesF(newChargesMoy) }, [PBTot]) // 仅在PBTot变化时执行
内容的提问来源于stack exchange,提问作者Aliénor
相关产品推荐
相关产品推荐

