我正在尝试在React / Redux中创建一个航班搜索应用程序,在主屏幕中将显示我的所有航班结果,并在侧边栏中显示不同类型的过滤器作为复选框。 (例如,请参阅this example
过滤器按类型分组,例如出发站,到站,出发时间等。所有过滤元素都是在一个标准化的嵌套状态下创建的,其中每个元素都具有以下属性:
"type": "airlines", // this is the group type
"checked": true, // will be switched true or false
"label": "Brittish Airways" // this is the display label
当我单击React视图中的一个复选框时,将触发以下操作:
export function filterFlightOffers(item, index) {
return {
type: 'FILTER_FLIGHT_OFFERS',
grouptype,
id
}
}
我希望我的redux reducer更新状态(切换检查值)并返回新状态(例如,immutable)。在线查看这些示例,我会像使用扩展运算符复制新状态等解决方案,例如: ...状态并用切换的检查项目更新spefic元素,例如{[action.id]:选中,!已检查}。
但我不能让它工作,我认为由于我有一个深度嵌套状态的事实。因此我删除了动作和reducer的复杂性,并做了一个简单的jsfiddle,它应该只是console.log一个新的不可变的'改变了'状态。
有人可以帮助我吗?
http://jsfiddle.net/gzco1yp7/4/
谢谢!
答案 0 :(得分:1)
如果你的州看起来像这样:
{
result: [1,2,3,4],
entities: {
searchitems: {
1: {
"type": "matchAirlines",
"checked": false,
"label": "Match airlines"
},
2: {
"type": "airlines",
"checked": true,
"label": "Air France"
},
3: {
"type": "airlines",
"checked": true,
"label": "Brittish Airways"
}
},
counts:
1: { "count": 2001 },
2: { "count": 579 },
3: { "count": 554 }
}
}
}
......你的减速机看起来像这样:
function reducer(state, action) {
switch (action.type) {
case 'FILTER_FLIGHT_OFFERS':
return {
...state,
entities: {
...state.entities,
searchItems: Object.keys(state.entities.searchItems).reduce((newItems, id) => {
const oldItem = state.entities.searchItems[id];
if (oldItem.type === action.groupType) {
newItems[id] = { ...oldItem, checked: id === action.id };
} else {
newItems[id] = oldItem;
}
return newItems;
}, {})
}
};
}
return state;
}
如果您使用combineReducers并为您的searchItem创建一个reducer,则会更简单。而lodash也可以简化事情:
import mapValues from 'lodash/mapValues';
function searchItemsReducer(state, action) {
switch (action.type) {
case 'FILTER_FLIGHT_OFFERS':
return mapValues(state, (oldItem, id) => (
oldItem.type === action.groupType
? { ...oldItem, checked: id === action.id };
: oldItem
));
}
return state;
}