2016-11-19 12 views
5

zbudowałem wózku aplikację z tego reduktora w reactjs/Redux:Jak mogę przełączać właściwości w reduktorze?

const initialState = { 
    items: [], 
    cartOpen: false, 
    total: 0 
} 

const Cart = (state = initialState, action) => { 
    switch (action.type) { 
     case 'ADD_TO_CART': 
      let newstate = [...state, action.payload]; 
      var newTotal = 0; 
      newstate.forEach(it => { 
       newTotal += it.item.price; 
      }); 
      newstate.total = newTotal; 
      newstate.cartOpen =true 
      return newstate; 

     case 'TOGGLE_CART': 
      debugger; 
      return !state.cartOpen; 

     default: 
      return state 
    } 
} 

export default Cart; 

Próbuję ustawić stan na wózku czyli otwarty, ale kiedy sprawdzić dzienniki własnością koszyk jest aktualizowana, a nie cartOpen własność?

Odpowiedz

7

Redux zakłada, że ​​nigdy nie mutują obiekty to daje wam w reduktorze . Za każdym razem musisz zwrócić nowy obiekt stanu. Nawet jeśli nie używasz biblioteki takiej jak Immutable, musisz całkowicie unikać mutacji.

case 'TOGGLE_CART': 
    return !state.cartOpen; 

Doing ^^ to mutowania swój stan (zgorszenie obiektu państwowej). Kiedy nie gwarantujesz niezmienności, Redux traci swoją przewidywalność i skuteczność.

Aby osiągnąć stan niezmienny, możemy użyć wanilii Object.assign lub jej bardziej eleganckiej alternatywy object spread syntax.

case 'TOGGLE_CART': 
    return { 
     ...state, 
     cartOpen: !state.cartOpen 
    } 
+0

Naprawdę nie zmieniam stanu, w którym właśnie zwracam wartość logiczną? –

+0

Przypadkowo nacisnąłem klawisz Enter, ok, tutaj jest reszta mojego poprzedniego komentarza: 'initialState = {a: 1, b: 2, cartOpen: false}' teraz, jeśli twój reduktor zwróci 'return! State.cartOpen', a następnie konsola .log (stan) da boolean 'true' (ale chciałeś' {a: 1, b: 2, cartOpen: true} '). Co oznacza, że ​​straciłeś wszystkie inne właściwości "a", "b" itd. W twoim obiekcie stanu. Zasadniczo zmutowałeś lub uszkodziłeś swój stan. –

1

Twój reduktor musi zawsze zwracać kompletny kawałek stanu aplikacji, za który jest odpowiedzialny. W przypadku TOGGLE_CART zwracana jest tylko wartość logiczna dla openCart.

Zamiast tworzyć kopię poprzedniego obiektu państwowego i tylko zaktualizować pojedynczą usługę, którą chcesz zmienić:

case 'TOGGLE_CART': 
    return Object.assign({}, state, { 
     cartOpen: !state.cartOpen 
    }); 
+0

Niesamowite dzięki koleś –