2016-08-18 8 views
1

Ich versuche, eine Flugsuche Anwendung in React/Redux, wo auf dem Hauptbildschirm alle meine Flug Ergebnisse angezeigt werden, und in der Seitenleiste, verschiedene Arten von Filtern als Kontrollkästchen werden angezeigt. (Als Beispiel siehe this exampleUpdate tief verschachtelten Zustand (normalisiert) in react redux

Die Filter von Typen gruppiert sind, zB Abfahrtsstationen, Ankunft Stationen, Abfahrtszeiten usw. Alle Filterelemente in einem normalisierten verschachtelten Zustand erzeugt werden, wobei jedes Element die folgenden Eigenschaften aufweist:

"type": "airlines",   // this is the group type 
"checked": true,    // will be switched true or false 
"label": "Brittish Airways" // this is the display label 

Als ich eines des Kontrollkästchen klicken Sie in meiner React Ansicht, wird die folgende Aktion ausgelöst werden:

export function filterFlightOffers(item, index) { 
    return { 
     type: 'FILTER_FLIGHT_OFFERS', 
     grouptype, 
     id 
    } 
} 

ich meinen redux Minderer möchte den Zustand (Schalter geprüft Wert) und gibt den neuen Status aktualisieren (zB ich mmutabel). Wenn ich die Beispiele online betrachte, reagiere ich auf Lösungen wie Kopieren eines neuen Zustands mit einem Spreizoperator, z. ... das spezifische Element mit dem umgeschalteten überprüften Element, z. {[action.id]: aktiviert,! aktiviert}.

Aber ich kann es einfach nicht funktionieren, denke ich aufgrund der Tatsache, dass ich einen tiefen verschachtelten Zustand habe .. Daher entfernte ich die Aktion und Reducer-Komplexität und machte eine einfache jsfiddle, die nur eine neue unveränderlich Status 'geändert'

Gibt es jemanden, der mir helfen könnte?

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

Vielen Dank!

+0

Warum verschachteln Sie '... state [action.id]' in 'state [action.id]'? Es wäre ein bisschen leichter zu helfen, wenn Sie erklären könnten, was auf Ihrer Aktion steht und was Sie damit machen wollen. Zum Beispiel versuchen Sie vielleicht, die Übung "action.id" mit "action.exercise" zu aktualisieren. Was du hier hast und der Zustand, den du in deiner Geige hast, stehen überhaupt nicht auf einer Linie. – ajmajmajma

+0

O, es tut mir wirklich leid. Der in der App angezeigte Code hat tatsächlich nichts mit meinem echten Code zu tun. Es war nur eine Kopie von einem Online-Beispiel, um das Prinzip zu zeigen. Der Code, an dem ich arbeite, ist in der Geige. Um die Dinge leichter zu machen, habe ich die ganze Aktion entfernt. Nur auf der Suche nach einer Lösung, um den Anfangszustand zu kopieren und ein bestimmtes Tiefenelement darin zu aktualisieren ... Ich werde meine erste Frage entsprechend aktualisieren. – user3611459

+0

Keine Sorge, zwischen diesen 2 Beispielen gibt es kein klares Bild von dem, was Sie versuchen zu tun. Wenn Sie klar beschreiben können, was Sie im Zustand zu ändern versuchen und wie (wie in dem, was Sie in Ihren Aktionen an Ihre Reduzierungen weitergeben), kann ich Ihnen zeigen, wie man es mit unveränderlichen ... – ajmajmajma

Antwort

1

Wenn Ihr Zustand etwas wie folgt aussieht:

{  
    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 } 
    } 
    } 
} 

... Ihr Minderer könnte wie folgt aussehen:

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

Dieses einfacher gemacht wird, wenn Sie combineReducers verwenden und ein Reduktions schaffen nur für Ihre searchItems. Und lodash kann auch Dinge vereinfachen:

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, besonders Der zweite Ratschlag brachte mich zum Nachdenken ... Warum sollte ich meinen Staat nicht viel einfacher machen? Ich konvertierte in ein einfaches Array von Objekten und bin jetzt in der Lage, .map und .filter zu verwenden, um Dinge zum Laufen zu bringen. Vielen Dank für deine Antwort! – user3611459

Verwandte Themen