状态变化后返回初始状态

时间:2016-07-09 09:09:00

标签: reactjs redux

我必须使用我的数据开发包含航班列表的网页。我的数据如下:

[
    {
      "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>航班。我不明白解决问题和返回初始状态的最佳方法是什么。

2 个答案:

答案 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;
};