React Native健身应用中Redux状态更新延迟问题排查与解决
React Native健身追踪应用Redux状态更新延迟问题及解决方法
开发一款React Native健身追踪应用时,遇到了Redux状态更新延迟的问题。该应用用于记录用户训练进度,通过workoutSessionSlice管理状态:
const initialState: IWorkoutSessionState = { currentTrackingEquipment: { createdOn: { seconds: 0, nanoseconds: 0 }, equipmentName: '', repetitions: [], results: [], repetitionIndex: 0, }, hasRunningSession: false, isTrackingEquipment: false, savedSessionEquipmentRecords: [], }; export const workoutSessionSlice = createSlice({ name: 'workoutSession', initialState, reducers: { saveEquipmentRecord: ( state: any, action: PayloadAction<IEquipmentRecord>, ) => { state.savedSessionEquipmentRecords.push(action.payload); }, addResult: (state: any, action: PayloadAction<IRepResult>) => { state.currentTrackingEquipment.results[ state.currentTrackingEquipment.repetitionIndex ] = action.payload; }, updateRepIndex: (state: any, action: PayloadAction<number>) => { state.currentTrackingEquipment.repetitionIndex = action.payload; }, }, });
问题现象
- 状态更新即时打印无变化:用户点击按钮添加训练结果时,
handleAddRep函数中打印的payload正确,但调用dispatch(addResult)后立即打印workOutSession状态,看不到刚更新的数据;但在函数外部手动打印状态时,能看到正确结果。
const handleAddRep = (success: boolean, nextRepIndex: boolean) => { console.log({ repetitions: workOutSession.currentTrackingEquipment.results[ workOutSession.currentTrackingEquipment.repetitionIndex ].repetitions, weight: equipmentTracking.wheelPickerValue, success, }); dispatch( addResult({ repetitions: workOutSession.currentTrackingEquipment.results[ workOutSession.currentTrackingEquipment.repetitionIndex ].repetitions, weight: equipmentTracking.wheelPickerValue, success, }), ); console.log(workOutSession); };
- 最后一条记录无法更新:保存训练记录时,
results数组的最后一个对象始终无法完成更新:
onPress={() => { Alert.alert('Successfully finished rep?', undefined, [ { text: 'Yes', onPress: () => { if ( workOutSession.currentTrackingEquipment .repetitionIndex === workOutSession.currentTrackingEquipment.results.length - 1 ) { handleAddRep(true, false); // 本应更新currentTrackingEquipment中的记录 Alert.alert('Finished tracking equipment?', undefined, [ { text: 'Yes', onPress: () => { handleFinishEquipmentTracking(); // 将当前追踪的设备记录添加到savedSessionEquipmentRecords }, }, { text: 'No, go back', }, ]); } else { handleAddRep(true, true); } }, }, ]); }}
尝试过直接修改对象属性而非替换整个对象,问题依然存在。
解决方案
问题根源在于原handleFinishEquipmentTracking函数传递了本地状态的副本,该副本是静态变量,不会随handleAddRep的状态更新而变化。通过两处修改解决问题:
- 修改
handleFinishEquipmentTracking,不再传递参数:
const handleFinishEquipmentTracking = () => { dispatch(saveEquipmentRecord()); };
- 修改
saveEquipmentRecordreducer,直接从state中获取数据:
原代码:
saveEquipmentRecord: ( state: any, action: PayloadAction<IEquipmentRecord>, ) => { state.savedSessionEquipmentRecords.push(action.payload); },
修改后:
saveEquipmentRecord: (state: any) => { state.savedSessionEquipmentRecords.push(state.currentTrackingEquipment); },
内容的提问来源于stack exchange,提问作者LuMaxIe
相关产品推荐
相关产品推荐

