2017-03-07 143 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