2015-12-24 114 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