I'm currently facing some issues with the Redux and React Native code provided below.
The goal is to build a workout tracking application where users can input their progress. I've implemented a 'workoutSessionSlice' to manage the state.
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;
},
},
});
The user interacts with the app by using specific equipment and recording their progress for each repetition. However, there seems to be a delay in updating the state, as evidenced by logging the payload and state within a button function:
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);
};
The issue of delayed state update persists even when attempting to save a record, preventing the last object in the results array from being updated properly.
onPress={() => {
Alert.alert('Successfully finished rep?', undefined, [
{
text: 'Yes',
onPress: () => {
if (
workOutSession.currentTrackingEquipment
.repetitionIndex ===
workOutSession.currentTrackingEquipment.results.length - 1
) {
handleAddRep(true, false);
Alert.alert('Finished tracking equipment?', undefined, [
{
text: 'Yes',
onPress: () => {
handleFinishEquipmentTracking();
},
},
{
text: 'No, go back',
},
]);
} else {
handleAddRep(true, true);
}
},
},
]);
}}
I've attempted strategies like directly modifying values at object keys instead of replacing entire objects, but to no avail. Any assistance would be greatly appreciated!
Solved! Special thanks to Phry.
In order to resolve the issue, modifications were made as follows:
Prior to this change, 'handleFinishEequipmentTracking' was called within the code:
const handleFinishEquipmentTracking = () => {
dispatch(
saveEquipmentRecord({
createdOn: workOutSession.currentTrackingEquipment.createdOn,
equipmentName: workOutSession.currentTrackingEquipment.equipmentName,
repetitions: workOutSession.currentTrackingEquipment.repetitions,
results: workOutSession.currentTrackingEquipment.results,
repetitionIndex:
workOutSession.currentTrackingEquipment.repetitionIndex,
}),
);
};
The parameter provided in 'saveEquipmentRecord', explained by Phry, is a local variable and does not update when the state changes via 'handleAddRep'. Two simple adjustments were made to address this:
const handleFinishEquipmentTracking = () => {
dispatch(saveEquipmentRecord());
};
Additionally, in the reducer function, changes were made to ensure that the source of data for saved equipment records comes directly from the state itself rather than a copy stored in a local variable:
Previous approach:
saveEquipmentRecord: (
state: any,
action: PayloadAction<IEquipmentRecord>,
) => {
state.savedSessionEquipmentRecords.push(action.payload);
},
Revised implementation:
saveEquipmentRecord: (state: any) => {
state.savedSessionEquipmentRecords.push(state.currentTrackinEquipment);
},