2016-12-27 27 views
0

我需要一點幫助,在我的redux reducer中使用Object.assign更新對象的內部元素。使用Object.assign更新對象的內部元素

爲了更好地解釋場景,我使用了NBA球隊。我在我的redux商店有一個NBA對象。我現在只想更新特定團隊的團隊成員。我的NBA物體看起來是這樣的:

{ 
    teams: [ 
     { 
      teamId: 123, 
      teamName: "Los Angeles Lakers" 
      teamMembers: [ 
      {id: "kbryant", fullName: "Kobe Bryant"}, 
      {id: "bingram", fullName: "Brandon Ingram"} 
      ] 
     }, 
     { 
      teamId: 234, 
      teamName: "Miami Heat" 
      teamMembers: [ 
      {id: "cbosh", fullName: "Chris Bosh"}, 
      {id: "tjohnson", fullName: "Tyler Johnson"} 
      ] 
     } 
    ] 
} 

我通過行動即action.teamId和action.members同時通過teamId和成員的減速。

這是我到目前爲止有:

Object.assign({}, state, { 
    nba: Object.assign({}, state.nba, { 
     teams: Object.assign({}, state.nba.teams, { 
     teamId[action.teamId] // I'm stuck here... 
     }) 
    }) 
}) 

如何更新特定團隊的teamMembers?我知道我幾乎在那裏,但可以使用一點幫助。謝謝。

+1

可能的重複[在redux存儲中更新嵌套數據](http://stackoverflow.com/questions/32135779/updating-nested-data-in-redux-store) –

+0

不重複。此外,該問題的建議不適用。我只使用Object.assign。 – Sam

+0

你可以在[IIFE](http://benalman.com/news/2010/11/immediately-invoked-function-expression/)中打包相關的'Object.assign'調用並在那裏做一些工作,包括任何數據突變。只要確保mutate並'返回'Object.assign()'創建的新對象。 –

回答

1

您可以使用動態索引屬性擴展您的代碼,該屬性旨在確定teams陣列中哪些條目需要更新。通過將動態表達式包裝在方括號中,ES6語法允許在對象文字中使用動態屬性,如下所示:{ [index]: value },其中index是一個變量或其他表達式。

下面是最終的解決方案:

function getNewState(state, action) { 
 
    var index = state.nba.teams.findIndex(t => t.teamId == action.teamId); 
 
    if (index == -1) return state; // team not found 
 
    return Object.assign({}, state, { 
 
     nba: Object.assign({}, state.nba, { 
 
      teams: Object.assign([], state.nba.teams, { 
 
       [index]: Object.assign({}, state.nba.teams[index], { 
 
        teamMembers: action.teamMembers 
 
       }) 
 
      }) 
 
     }) 
 
    }); 
 
} 
 

 
var state = { 
 
    nba: { 
 
     teams: [{ 
 
      teamId: 123, 
 
      teamName: "Los Angeles Lakers", 
 
      teamMembers: [ 
 
       {id: "kbryant", fullName: "Kobe Bryant"}, 
 
       {id: "bingram", fullName: "Brandon Ingram"} 
 
      ] 
 
     }, { 
 
      teamId: 234, 
 
      teamName: "Miami Heat", 
 
      teamMembers: [ 
 
       {id: "cbosh", fullName: "Chris Bosh"}, 
 
       {id: "tjohnson", fullName: "Tyler Johnson"} 
 
      ] 
 
     }] 
 
    } 
 
}; 
 

 
var action = { teamId: 123, teamMembers: [{id: "lnance", fullName: "Larry Nance"}] }; 
 
var newState = getNewState(state, action); 
 
console.log(newState);
.as-console-wrapper { max-height: 100% !important; top: 0; }

注意,這種操作變得更容易像Immutable圖書館很多。

+0

我認爲這是一個很好的解決方案,即找出索引然後更新值。它還需要我花一段時間才能實現。在調試一段時間後,我試圖弄清楚發生了什麼,在更新過程中我意識到 - 因爲我使用的是Object.assign,所以我將teamMembers從一個數組轉換爲一個對象,最終打破了我的其他代碼。因此,我沒有使用Object.assign創建teamMembers的新副本,而是使用了slice,並且它工作正常。我會研究不可變的庫。謝謝。 – Sam

+0

很高興聽到它解決。我認爲'Object.assign'也應該可以工作,但是通過提供一個空數組作爲第一個參數,以確保它始終是一個數組:'Object.assign([],...)'。我剛纔更新了它。但'切片'當然也好。 – trincot

+0

我不知道我可以使用Object.assign和一個空數組。剛學了一件事。你一直非常有幫助。真的很感激它!我會爲你的答案投票。 – Sam