2016-08-18 5 views
1

Я пытаюсь создать приложение поиска рейсов в React/Redux, где на главном экране будут показаны все мои результаты полета, а на боковой панели - различные фильтры, отображаются флажки. (В качестве примера см this exampleОбновление глубокого вложенного состояния (нормализованного) в реакции redux

Фильтры сгруппированы по типам, например, станции отправления, прибытия станций, вылет раза и т.д. Все Фильтроэлементы созданные в одном нормализованного вложенной состоянии, в котором каждый элемент имеет следующие свойства:

"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 редуктора для обновления состояния (переключатель проверяется значение) и вернуть новое состояние (например, i mmutable). Рассматривая примеры онлайн, я реагирую на такие решения, как копирование нового состояния с помощью оператора с расширением, например. ... состояние и обновление специфицированного элемента с включенным отмеченным элементом, например. {[action.id]: checked,! checked}.

Но я просто не могу заставить его работать, я думаю, из-за того, что у меня есть глубокое вложенное состояние. Поэтому я удалил сложность действия и редуктора и сделал простой jsfiddle, который должен просто console.log новый неизменный «изменено» состояние.

Есть ли кто-нибудь, кто мог бы мне помочь?

http://jsfiddle.net/gzco1yp7/4/

Спасибо!

+0

Почему вы вложенные '... state [action.id]' inside' state [action.id] '? Было бы немного легче помочь, если бы вы могли объяснить, что находится на вашем действии и что вы пытаетесь с этим сделать. Например, возможно, вы пытаетесь обновить упражнение 'action.id' с помощью' action.exercise'. То, что у вас здесь, и состояние, которое у вас есть на вашей скрипке, вообще не выстраивается. – ajmajmajma

+0

О, мне очень жаль. Код, отображаемый в приложении, не имеет ничего общего с моим реальным кодом. Это была просто копия онлайн-примера, чтобы показать принцип. Код, над которым я работаю, находится в скрипке. Для облегчения работы я удалил все действие. Только ищет решение для копирования исходного состояния и обновления определенного глубокого элемента в нем ... Я соответственно обновлю свой первоначальный вопрос. – user3611459

+0

Не беспокойтесь, между этими двумя примерами нет четкой картины того, что вы пытаетесь сделать. Если вы можете четко описать *, что * вы пытаетесь изменить в состоянии и как (как в том, что вы передаете в своих действиях вашим редукторам), я могу показать вам, как это сделать с неизменяемым ... – ajmajmajma

ответ

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 и создать редуктор только для ваши поисковые запросы. И 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; 
} 
+0

Thnx, особенно второй совет заставлял меня думать ... почему бы не сделать мое состояние намного легче. Я преобразовал в простой массив объектов, и теперь я могу использовать .map и .filter, чтобы заставить работу работать. Большое спасибо за ваш ответ! – user3611459

Смежные вопросы