javascript - 如何在不变异的情况下正确更新 redux 数组中的项目?
问题描述
const state = [
{
list: []
}
];
该列表是学生对象的列表,例如:
list: [
{ id: 1, name: "Mark", attendance: true },
{ id: 2, name: "John", attendance: false }
]
我有一个按钮可以触发对 API 的发布请求,以将出勤率更改为 true。发布请求返回已更改的学生对象,例如:
{ id: 2, name: "John", attendance: true }
这工作正常,如果没有错误,将调度ATTENDANCE_SUCCESS
.
现在,通过这种设置:
export function students(state, action) {
let latestState = state[state.length - 1],
newState = Object.assign({}, latestState);
switch (action.type) {
case "ATTENDANCE_SUCCESS":
if (action.res.errorCode == 0) {
// Need to change redux state 'attendance' value to true for a student with ID returned from the POST request
}
}
最初,我做了:
const studentChanged = newState.list.find(function(student) {
return (
student.id ===
action.res.data.id
);
});
studentChanged.attendance = true;
但它改变了 redux 存储中的状态(尽管我不确定它是如何发生的,因为我假设 newState 已经是一个副本)。
什么是正确的方法?
解决方案
以下将更新数组中的单个项目。这里的关键方面是,如果id
项目的 与来自操作有效负载的 不匹配id
,它会返回未更改的项目,否则它会更新attendance
属性。Array.prototype.map
返回一个新数组,因此它是不可变的。
export function students(state, action) {
switch (action.type) {
case "ATTENDANCE_SUCCESS":
if (action.res.errorCode == 0) {
return state.map(student => {
// we want to leave non matching items unaltered
if (student.id !== action.res.data.id) {
return student;
}
return { ...student, attendance: true };
});
}
return state;
default:
return state;
}
}
这是一个StackBlitz来演示功能。
希望这会有所帮助!
推荐阅读
- python - 将表格保存在数据库中
- python - 为什么执行 form.is_valid() 会导致删除不在 django 表单中的实例字段?
- php - 如何将这三个 php 提要合并为一个提要
- django - 如何在 Django 中只用一个查询来查询 2 个不同的表?
- r - 查找和计算符合条件的连续观测值
- java - Java : Quartz 调度程序 - 有没有一种方法可以让我运行接下来的五次调度作业
- java - 使用装订线按钮运行测试总是会创建一个新配置
- angular - 如何在 .subscribe 中调用函数
- api - 断言值与正文中的字段不匹配
- android - Cordova 构建错误