我很难理解我在下面的 Redux 和 React native 代码中做错了什么。
我正在尝试创建一个锻炼跟踪应用程序,用户可以在其中输入他们的锻炼进度。我创建了一个“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;
},
},
});
用户使用某件设备,并通过按钮将每次重复的结果添加到状态中。我注意到,当我在该按钮的功能中 console.log 有效负载和状态时,状态存在“延迟”:
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);
};
控制台:
Object {
"repetitions": 15,
"success": true,
"weight": 100,
}
Object {
"currentTrackingEquipment": Object {
"createdOn": Object {
"nanoseconds": 735000000,
"seconds": 1671364848,
},
"equipmentName": "Bench-press-incline",
"repetitionIndex": 0,
"repetitions": Array [
15,
12,
7,
],
"results": Array [
Object { // expected this object to be replaced
"repetitions": 15,
"success": false,
"weight": 0,
},
Object {
"repetitions": 12,
"success": false,
"weight": 0,
},
Object {
"repetitions": 7,
"success": false,
"weight": 0,
},
],
},
"hasRunningSession": true,
"isTrackingEquipment": true,
"savedSessionEquipmentRecords": Array [],
}
当我在按钮功能之外手动记录状态时,我确实在数组和对象中看到了正确的数据:
Object {
"currentTrackingEquipment": Object {
"createdOn": Object {
"nanoseconds": 735000000,
"seconds": 1671364848,
},
"equipmentName": "Bench-press-incline",
"repetitionIndex": 1,
"repetitions": Array [
15,
12,
7,
],
"results": Array [
Object {
"repetitions": 15,
"success": true,
"weight": 100,
},
Object {
"repetitions": 12,
"success": false,
"weight": 0,
},
Object {
"repetitions": 7,
"success": false,
"weight": 0,
},
],
},
"hasRunningSession": true,
"isTrackingEquipment": true,
"savedSessionEquipmentRecords": Array [],
}
问题是,当我想要保存记录时,也会发生这种“延迟”,导致结果数组中的最后一个对象无法更新。
onPress={() => {
Alert.alert('Successfully finished rep?', undefined, [
{
text: 'Yes',
onPress: () => {
if (
workOutSession.currentTrackingEquipment
.repetitionIndex ===
workOutSession.currentTrackingEquipment.results.length - 1
) {
handleAddRep(true, false); // Should update rep in "currentTrackingEquipment"
Alert.alert('Finished tracking equipment?', undefined, [
{
text: 'Yes',
onPress: () => {
handleFinishEquipmentTracking(); // adds current tracking equipment to "savedSessionEquipmentRecords"
},
},
{
text: 'No, go back',
},
]);
} else {
handleAddRep(true, true);
}
},
},
]);
}}
我尝试在对象键上设置值,而不是替换整个对象,但这效果不佳。任何帮助将不胜感激!
解决了!感谢弗里。
以下是我为使其工作而进行的更改: 我将上面的代码称为“handleFinishEequipmentTracking”,如下所示:
const handleFinishEquipmentTracking = () => {
dispatch(
saveEquipmentRecord({
createdOn: workOutSession.currentTrackingEquipment.createdOn,
equipmentName: workOutSession.currentTrackingEquipment.equipmentName,
repetitions: workOutSession.currentTrackingEquipment.repetitions,
results: workOutSession.currentTrackingEquipment.results,
repetitionIndex:
workOutSession.currentTrackingEquipment.repetitionIndex,
}),
);
};
正如 Phry 解释的那样,“saveEquipmentRecord”中作为参数给出的对象是一个局部变量,并且当“handleAddRep”更改状态时不会更新。我必须在“saveEquipmentRecord”函数中进行两个简单的更改:
const handleFinishEquipmentTracking = () => {
dispatch(saveEquipmentRecord());
};
在 reducer 中,我更改了保存的 EquipmentRecords 的数据源是状态本身,而不是局部变量中状态的副本:
来自:
saveEquipmentRecord: (
state: any,
action: PayloadAction<IEquipmentRecord>,
) => {
state.savedSessionEquipmentRecords.push(action.payload);
},
至:
saveEquipmentRecord: (state: any) => {
state.savedSessionEquipmentRecords.push(state.currentTrackinEquipment);
},
最佳答案
没有“延迟” - 您正在查看永远不会更新的旧(“陈旧”)数据。
请参阅此示例:
let state = { foo: 1 }
const s = state
state = { foo: 2 }
// s is now { foo: 1 } and state is { foo: 2 }
仅仅因为您的状态更新为新值(并且它将是一个全新的对象,因为状态更新是不可变的)并不意味着您的局部变量将会更新 - 它们仍然会指向之前的相同值。
将来,该组件将重新渲染 - 然后 const something = useSelector(...)
将重新执行。然后你就有了一个具有相同名称的新变量,并且该新变量将具有新值(但很快又会过时)。
关于typescript - 是什么导致 Redux 中更新状态出现 "Delay"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74841527/