2016-09-07 7 views
0

Ich habe einen Haken gefunden, wenn Update-Zustand mit Redux und Reactive-Redux. Wenn ich ein einzelnes Statussegment aktualisiere, werden alle anderen entfernt. Ich weiß, dass die Antwort einfach sein wird, aber ich kann es nicht herausfinden und habe nichts anderes online gefunden.Wie aktualisiere ich bestimmte Schicht von Redux-Zustand in React

So zu klären, hier ist mein Minderer:

const initialState = { 
     selectedLevel: null, 
     selectedVenue: null, 
     selectedUnitNumber: null, 
     selectedUnitName: null, 
     selectedYear: null 
} 

export default (state = initialState, action) => { 
    console.log('reducer: ', action); 
    switch (action.type){ 
     case 'CHOOSE_LEVEL': 
      return action.payload; 
     case 'CHOOSE_VENUE': 
      return action.payload; 
     case 'CHOOSE_UNIT': 
      return action.payload; 
     case 'SHOW_COURSES': 
      return action.payload; 
    } 

    return state; 
} 

Und mein kombinieren Minderer:

workshopSelection: { 
    selectedLevel: null, 
    selectedVenue: null, 
    selectedUnitNumber: null, 
    selectedUnitName: null, 
    selectedYear: null 
} 

Aber wenn ich benutze:

export default combineReducers({ 
    workshopSelection: WorkshopSelectReducer 
}); 

Also mein Ausgangszustand wie folgt aussieht Einer meiner Ersteller von Aktionen, zum Beispiel:

export function chooseVenue(venue){ 
    return { 
     type: 'CHOOSE_VENUE', 
     payload: { 
      selectedVenue: venue 
     } 
    } 
} 

ich am Ende mit Zustand wie folgt aussehen:

workshopSelection: { 
    selectedVenue: 'London', 
} 

Der ganze Rest des Staates in diesem Objekt, das nicht von dieser Aktion betroffen Schöpfer wurde komplett ausgelöscht wurde. Stattdessen möchte ich nur, dass alle anderen Einträge so bleiben, wie sie sind, mit ihren ursprünglichen Werten - null in diesem Beispiel, oder was auch immer anderen Wert ihnen zugewiesen wurde.

Ich hoffe, dass alles einen Sinn ergibt.

Prost!

Antwort

2

Sie ersetzen grundsätzlich ein Objekt (vorheriger Zustand) durch ein anderes (Ihre Nutzlast, die auch ein Objekt ist).

In Bezug auf die Standard-JS, wäre dies der equlivalent sein, was Ihr tut Minderer:

var action = { 
    type: 'CHOOSE_VENUE', 
    payload: { 
     selectedVenue: venue 
    } 
}; 

var state = action.payload; 

Der einfachste Weg, dies zu beheben wäre mit Object spread properties:

export default (state = initialState, action) => { 
    switch (action.type){ 
     case 'CHOOSE_LEVEL': 
     case 'CHOOSE_VENUE': 
     case 'CHOOSE_UNIT': 
     case 'SHOW_COURSES': 
      // Watch out, fall-through used here 
      return { 
       ...state, 

       ...action.payload 
      }; 
    } 

    return state; 
} 

... aber Da dies noch in der Versuchsphase ist, müssen Sie andere Möglichkeiten verwenden, um vorherige Eigenschaften zu klonen und dann die neuen zu überschreiben. Eine doppelte for ... in Schleife ein einfacher sein könnte:

export default (state = initialState, action) => { 
    switch (action.type){ 
     case 'CHOOSE_LEVEL': 
     case 'CHOOSE_VENUE': 
     case 'CHOOSE_UNIT': 
     case 'SHOW_COURSES': 
      // Watch out, fall-through used here 
      const newState = {}; 

      // Note: No key-checks in this example 
      for (let key in state) { 
       newState[key] = state[key]; 
      } 
      for (let key in action.payload) { 
       newState[key] = action.payload[key]; 
      } 

      return newState; 
    } 

    return state; 
} 
+0

Brilliant - zweite Option funktioniert, danke. Übrigens habe ich versucht, Spread-Operatoren zu verwenden, aber es warf immer einen Syntaxfehler beim ersten '. '- liegt das an ihrem experimentellen Charakter? Ich benutze webpack und babel, um meinen Code zu transpilieren und Spread-Operatoren in anderen Teilen der Anwendung ohne Probleme verwendet zu haben, aber aus irgendeinem Grund hat es auf diesem einen nicht funktioniert. Irgendeine Idee, warum das ist - die ES6-Syntax ist viel schöner, also möchte ich es verwenden, wo immer es möglich ist! – Chris

+0

Ich gehe davon aus, dass Sie Array Spread verwendet haben, was Teil der ES6-Syntax ist.Der Objekt-Spread ist etwas anderes, momentan in Stufe 2 (so müssen wir leider mindestens bis ES2018 warten). Wenn Sie Babel 6 verwenden, benötigen Sie [Objekt Rest Spread Plugin] (https://babeljs.io/docs/plugins/transform-object-rest-spread/). – mdziekon

+0

Natürlich - ja, die anderen Zeiten, die ich es benutzt habe, waren mit Arrays, keine Objekte. Brilliant, danke für deine Hilfe! – Chris

0

Halten Sie Ihre Nutzlast Objekt als flach auf Aktionen Macher wie unten gezeigt ...

export function chooseVenue(venue){ 
    return { 
     type: 'CHOOSE_VENUE', 
     selectedVenue: venue 
    } 
} 

und Ihre Minderer wie unten ändern (gegebenes Beispiel ist für Aktualisieren Sie den Veranstaltungsort, machen Sie das gleiche für andere Fälle auch ...)

export default (state = initialState, action) => { 
    let newState = Object.assign({}, state); // Take copy of the old state 
    switch (action.type){ 
     case 'CHOOSE_LEVEL': 
     case 'CHOOSE_VENUE': 
       newState.selectedVenue = action.selectedVenue; // mutate the newState with payload 
       break; 
     case 'CHOOSE_UNIT': 
     case 'SHOW_COURSES': 
     default : 
      return newState; 
    } 

    return newState; // Returns the newState; 
} 
Verwandte Themen