2017-03-07 111 views
1

我在我的react-redux应用程序中设置了动作和缩减器。我需要一个函数来更新状态中的属性并将对象添加到其列表中,如果可能的话使用扩展语法。这是我到目前为止有:如何将对象属性添加到状态中的另一个属性?

const defaultState = { 
    genres: {} 
} 

export default function(state = defaultState, action) { 
    switch(action.type) { 
    case 'ADD_GENRE': 
     return { 
     ...state, 
     genres[action.name]: action.list //new code here 
     } 
    default: 
     return state; 
    } 
} 

我需要的类型物业使用它的属性名像这样要像一个数组动态访问:

const getMusicFromGenre = (genre) => { 
    return state.genres[genre]; 
} 

减速机应该接受以下动作,然后修改相应的状态:

// action 
{ 
    type: 'ADD_GENRE, 
    name: 'Rock', 
    list: ['Bohemian Rhapsody', 'Stairway to Heaven', 'Hotel California'] 
} 

// old state 
{ 
    genres: { 
    "Pop": ['Billie Jean', 'Uptown Funk, 'Hey Jude'] 
    } 
} 

// new state 
{ 
    genres: { 
    "Pop": ['Billie Jean', 'Uptown Funk, 'Hey Jude'], 
    "Rock": ['Bohemian Rhapsody', 'Stairway to Heaven', 'Hotel California'] 
    } 
} 

如果有必要,我愿意使用不同的方法。

回答

3

你在正确的轨道上,但需要分别处理每个级别的嵌套。下面是我写的http://redux.js.org/docs/recipes/reducers/ImmutableUpdatePatterns.html一个例子:

function updateVeryNestedField(state, action) { 
    return { 
     ....state, 
     first : { 
      ...state.first, 
      second : { 
       ...state.first.second, 
       [action.someId] : { 
        ...state.first.second[action.someId], 
        fourth : action.someValue 
       } 
      } 
     } 
    } 
} 

您可能还需要阅读一些,我在http://redux.js.org/docs/recipes/reducers/PrerequisiteConcepts.html#immutable-data-managementhttps://github.com/markerikson/react-redux-links/blob/master/immutable-data.md链接不可变数据处理的文章。

+0

我试图我自己找到解决方案,但问题太难以谷歌。感谢您的链接,明天我们将通过一杯明天的咖啡读取这些信息 – Brian

2

immutability-helper是一个非常有用的库进行状态更新。在您的情况会这样来使用,这将创造一个新的数组,如果没有现有的项目,或Concat的配合动作的列表中的现有项目,如果有预先存在的项目:

import update from 'immutability-helper'; 

const defaultState = { 
    genres: {} 
} 

const createOrUpdateList = (prev, list) => { 
    if (!Array.isArray(prev)) { 
     return list; 
    } 
    return prev.concat(list); 
    // or return [...prev, ...list] if you prefer 
} 

export default function(state = defaultState, action) { 
    switch(action.type) { 
    case 'ADD_GENRE': 
     return update(state, { 
      genres: { 
       [action.name]: { 
        $apply: prev => createOrUpdate(prev, action.list) 
       } 
      } 
     }); 
    default: 
     return state; 
    } 
} 
+0

这是一个有用的插件,使代码更易于查看。谢谢 – Brian