2015-12-24 168 views
3

我正在嘗試向state中的數組添加一個元素,並更改另一個數組元素的屬性。假設我們有以下state結構:在Redux中更改狀態

{ 
    menuItems: [{ 
    href: '/', 
    active: true 
    }] 
} 

派遣ADD_MENU_ITEM動作後,我想這state落得:

{ 
    menuItems: [{ 
    href: '/new', 
    active: true 
    }, { 
    href: '/', 
    active: false, 
    }] 
} 

我曾嘗試在一些時尚的終極版reducers管理這樣的:

function reducer(state = {}, action) { 
    switch (action.type) { 
    case ADD_MENU_ITEM: { 
     let menuItems = state.menuItems; 
     let newMenuItem = action.newMenuItem; 

     // First try 
     menuItems[0].active = false; 
     menuItems.unshift(newMenuItem); 
     state = Object.assign({}, state, { menuItems: menuItems }); 

     // Second try 
     menuItems[0].active = false; 
     menuItems.unshift(newMenuItem); 
     state = Object.assign({}, state, {menuItems: Object.assign([], menuItems)}); 

     // Third try 
     menuItems[0].active = false; 
     state = (Object.assign({}, state, { 
     menuItems: [ 
      Object.assign({}, newMenuItem), 
      ...menuItems 
     ] 
     })); 

     // Fourth try 
     menuItems[0].active = false; 
     state = update(state, { 
     menuItems: {$unshift: new Array(newMenuItem)} 
     }); 

     console.log(state); 
     return state; 
    } 
    } 
} 

在第四次嘗試中,我使用的是React的Immutability Helpers,但它永遠不會起作用。我在返回狀態並將其記錄正確之前將狀態記錄到了控制檯,但在記錄組件的內部記錄時,儘管active成員設置爲false,但menuItems數組不會添加第一個項目,儘管active成員被設置爲。

我會做什麼錯?

回答

8

減速機中的狀態應該是不可變的,因此不應該修改。還建議儘可能平整對象。

在您的情況您最初的狀態可能是一個數組作爲這樣的:

[{ 
    href: '/', 
    active: true 
    }] 

在你減速,試圖返回一個全新的數組如下:

function reducer(state = {}, action) { 
    switch (action.type) { 
    case ADD_MENU_ITEM: { 
     return [ 
     action.newMenuItem, 
     ...state.map(item => Object.assign({}, item, { active: false })) 
     ]; 
    } 
    } 
} 

有關減速器的更多信息可在這裏找到:Redux Reducers Documentation

有用的文件摘錄:

減速機保持純淨非常重要。在減速機內你永遠不應該做的事情:

  • 改變它的參數;
  • 執行API調用和路由轉換等副作用;
  • 調用非純函數,例如Date.now()或Math.random()。

更多信息ADDED

在你減速,併爲所有四次嘗試,你在返回之前修改現有狀態。

這會導致react-redux檢查您的狀態是否發生了變化,因爲上一個狀態和下一個狀態都指向同一個對象,所以不會看到任何更改。

這裏是我這裏指的是線:

的第一次嘗試:

// This line modifies the existing state. 
    state = Object.assign({}, state, { menuItems: menuItems }); 

第二次嘗試:

// This line modifies the existing state. 
    state = Object.assign({}, state, {menuItems: Object.assign([], menuItems)}); 

第三次嘗試:

// This line modifies the existing state. 
    state = (Object.assign({}, state, { 
    menuItems: [ 
     Object.assign({}, newMenuItem), 
     ...menuItems 
    ] 
    })); 

第四次嘗試:

// This line modifies the existing state. 
    state = update(state, { 
    menuItems: {$unshift: new Array(newMenuItem)} 
    }); 
+0

鏈接到終極版異徑文檔改變:http://redux.js.org/docs/basics/Reducers.html – Anass