我必须使用我的数据开发包含航班列表的网页。我的数据如下:
[
{
"id": 123,
"direction": {
"from": "Moscow",
"to": "Berlin"
},
"arrival": "2016-06-08T19:52:27.979Z",
"departure": "2016-06-08T17:51:20.979Z",
"carrier": "S7"
},
{
"id": 133,
"direction": {
"from": "Moscow",
"to": "Samara"
},
"arrival": "2016-09-08T13:52:27.979Z",
"departure": "2016-08-08T17:51:20.979Z",
"carrier": "KLM"
},
{
"id": 193,
"direction": {
"from": "Moscow",
"to": "New York"
},
"arrival": "2016-06-08T21:52:27.979Z",
"departure": "2016-06-08T17:51:20.979Z",
"carrier": "Aeroflot"
}
]
运营商也有一个简单的过滤器。它只是HTML中的select
标记,带有选项: All,Aeroflot,KLM,S7 以及onChange
事件上的监听器:
const mapDispatchToProps = (dispatch) => {
return {
onChangeHandler(event) {
if (event.target.value === 'All') {
dispatch(selectAllCarriers())
} else {
dispatch(selectCarrier(event.target.value))
}
}
}
};
当我选择 KLM 时,我会返回此状态:
[
{
"id": 133,
"direction": {
"from": "Moscow",
"to": "Samara"
},
"arrival": "2016-09-08T13:52:27.979Z",
"departure": "2016-08-08T17:51:20.979Z",
"carrier": "KLM"
}
];
当我选择全部时,我必须返回完整的航班列表。我在reducer中实现了它:
const flights = (state = initialState, action) => {
switch(action.type) {
case 'SELECT_CARRIER':
if (action.carrier === 'All') {
return state
} else {
return state.filter(f => f.carrier === action.carrier);
}
default:
return state;
}
};
但是,如果我选择 KLM 并且在 All 之后我只有 KLM 航班,因为我的州现在只包含 KLM < / em>航班。我不明白解决问题和返回初始状态的最佳方法是什么。
答案 0 :(得分:4)
您需要使用选择器而不是从状态中删除数据。当您选择运营商时,您需要在商店中设置这是您正在使用的选择器,然后使用选择器进行过滤,但不要从商店中删除其他航班。
查看Dan Abramov关于在Redux中使用选择器的链接。 https://egghead.io/lessons/javascript-redux-colocating-selectors-with-reducers?course=building-react-applications-with-idiomatic-redux
答案 1 :(得分:3)
您应该过滤组件的select
功能中的原始数据,而不是在您的reducer中进行过滤。考虑一下这个小小的变化:
const initialState = {
flights: [],
filter: undefined
};
const flights = (state = initialState, action) => {
switch(action.type) {
case 'SELECT_CARRIER':
return {
...state,
filter: action.carrier
};
case 'SELECT_ALL':
return {
...state,
filter: undefined
};
default:
return state;
}
};
现在访问已过滤的航班:
const flightsSelector = (state) => {
if (state.filter) {
return state.flights.filter(f => f.carrier === state.filter);
}
return state.flights;
};