Arrays 如何在ReactJS reducer中正确更新redux状态?
我的Redux数据存储中有以下结构:Arrays 如何在ReactJS reducer中正确更新redux状态?,arrays,reactjs,redux,react-redux,Arrays,Reactjs,Redux,React Redux,我的Redux数据存储中有以下结构: { filterData: { 22421: { filterId: 22421, selectedFilters: [ { filterName: 'gender', text: 'Male', value: 'male'
{
filterData: {
22421: {
filterId: 22421,
selectedFilters: [
{
filterName: 'gender',
text: 'Male',
value: 'male'
},
{
filterName: 'gender',
text: 'female',
value: 'female'
}
]
}
22422: {
filterId: 22422,
selectedFilters: [
{
filterName: 'colour',
text: 'Blue',
value: 'blue'
},
{
filterName: 'animal',
text: 'sheep',
value: 'Sheep'
}
]
}
有人能告诉我使用正确的方法来更新selectedFilters数组而不直接改变状态吗?i、 e.如何在给定filterId的selectedFilters数组中添加/删除元素?通常使用非变异(即返回新对象,而不是修改现有对象)运算符和函数来完成:
- (
)用于对象和数组(用于添加和编辑)…
- ,对于数组(用于编辑和删除)
- 用于对象(用于编辑和添加)
selectedFilters
,您必须执行以下操作:
// Assuming you're inside a reducer function.
case SOME_ACTION:
// Returning the new state object, since there's a change inside.
return {
// Prepend old values of the state to this new object.
...state,
// Create a new value for the filters property,
// since—again—there's a change inside.
filterData: {
// Once again, copy all the old values of the filters property…
...state.filters,
// … and create a new value for the filter you want to edit.
// This one will be about removal of the filter.
22421: {
// Here we go again with the copy of the previous value.
...state.filters[22421],
// Since it's an array and we want to remove a value,
// the filter method will work the best.
selectedFilters:
state.filters[22421].selectedFilters.filter(
// Let's say you're removing a filter by its name and the name
// that needs to be removed comes from the action's payload.
selectedFilter => selectedFilter.name !== action.payload
)
},
// This one could be about addition of a new filter.
22422: {
...state.filters[22422],
// Spread works best for additions. It returns a new array
// with the old values being placed inside a new one.
selectedFilters: [
// You know the drill.
...state.filters[22422].selectedFilters,
// Add this new filter object to the new array of filters.
{
filterName: 'SomeName',
text: 'some text',
value: action.value // Let's say the value comes form the action.
}
]
},
}
}
此常量“复制旧值”是确保保留嵌套对象中的值所必需的,因为“排列”操作符以浅层方式复制属性
const someObj = {a: {b: 10}, c: 20}
const modifiedObj = {...someObj, a: {d: 30}}
// modifiedObj is {a: {d: 30}, c: 20}, instead of
// {a: {b: 10, d: 30}, c: 20} if spread created a deep copy.
正如你所看到的,这是一个有点平凡的事情。解决这个问题的一个方法是创建某种嵌套的reducer函数,这些函数将在独立的状态树上工作。然而,有时最好不要重新发明风团,使用已经可以用来解决这些问题的工具。例如。如果您想使用专用库来管理不可变状态(如另一个答案中建议的),请查看
我发现这个库比Immutable.js更易于使用(而且包的大小也会更小)感谢您的全面回复。我试图在向数组添加元素时让它工作,所以我尝试使用您提供的代码的这一部分。但是,我收到以下错误消息:“TypeError:无法将undefined或null转换为object”,selectedFilters突出显示。很难说,谢谢你的帮助。现在我明白了,我在响应中使用了
filters
而不是filterData
,所以这是第一条线索。第二个是示例中应该有[…state.filters[22422].selectedFilters、/*new filter*/]
(缺少selectedFilters
访问)。我已经解决了这两个问题,也许这会对你有所帮助。如果没有,您必须显示您的代码。谢谢您的帮助。我成功地解决了这个问题,这是由于我向一个操作传递了一个错误的值造成的。