2016-11-19 61 views
5

我建立了一个购物车的应用程序与此减速机在reactjs /终极版:如何在减速器中切换属性?

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; 

我想设置了车的状态,即开,但是当我检查日志的车属性更新,而不是cartOpen属性?

回答

7

终极版假定你永远不发生变异的 减速它给你的对象。 每一次,您都必须返回新的状态对象。 即使您没有使用类似Immutable的库,您也需要完全避免突变 。

case 'TOGGLE_CART': 
    return !state.cartOpen; 

做^^这是您的突变状态(破坏你的状态对象)。如果您不能保证不变性,Redux将失去其可预测性和效率。

要实现不可变状态,我们可以使用vanilla Object.assign或更优雅的替代品object spread syntax

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

我真的不改变状态我只是返回一个布尔值? –

+0

我不小心按了输入键,好的,这里是我以前评论的其余部分: 'initialState = {a:1,b:2,cartOpen:false}' 现在如果你的reducer返回'return!state.cartOpen',那么console .log(state)会产生一个布尔值“true”(但你​​想要'{a:1,b:2,cartOpen:true}')。这意味着你的状态对象中已经失去了所有其他属性'a','b'等。基本上你已经改变或破坏了你的状态。 –

1

您的减速器必须始终返回其负责的应用程序状态的完整切片。对于TOGGLE_CART,您只返回openCart的布尔值。

相反,创建以前的状态对象的副本,并只更新单个属性要更改:

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

真棒感谢兄弟 –