2016-08-18 81 views
0

在終極版保存的對象,數組中的替換對象我有一個減速,看起來像這樣一個對象數組:使用Javascript/Lodash

[ 
    {id:1, name:Mark, email:[email protected]}, 
    {id:2, name:Paul, email:[email protected]}, 
    {id:3,name:sally, email:[email protected]} 
] 

下面是我的減速器。到目前爲止,我可以通過下面的currentPeople減速機添加一個新的對象:

const INITIAL_STATE = { currentPeople:[]}; 

export default function(state = INITIAL_STATE, action) { 
    switch (action.type) { 
    case ADD_PERSON: 
     return {...state, currentPeople: [ ...state.currentPeople, action.payload]}; 
    } 
    return state; 
} 

但這裏是我卡住了。我可以使用lodash通過減速器更新一個人嗎? 如果我發了行動有效載荷是這樣的:

{id:1, name:Eric, email:[email protected]} 

我將能夠以1與新領域的標識更換對象?

回答

2

是的,你可以在一個陣列完全更新對象像你想。如果你不想要,你不需要改變你的數據結構。你可以這樣添加的情況下,你的減速機:

case UPDATE_PERSON: 
    return { 
     ...state, 
     currentPeople: state.currentPeople.map(person => { 
      if (person.id === action.payload.id) { 
       return action.payload; 
      } 

      return person; 
     }), 
    }; 

這可以被縮短爲好,使用隱式的回報和三元:

case UPDATE_PERSON: 
    return { 
     ...state, 
     currentPeople: state.currentPeople.map(person => (person.id === action.payload.id) ? action.payload : person), 
    }; 

米希爾的關於您的數據映射到一個對象的想法normalizr當然是一種可能性,從技術上來說,使用引用更新用戶而不是執行循環(初始映射完成後)會更快。但是如果你想保持你的數據結構,這種方法將起作用。另外,像這樣的映射只是更新對象的許多方法之一,並且需要瀏覽器對Array.prototype.map()的支持。你可以使用lodash indexOf()來找到你想要的用戶的索引(這很好,因爲它在成功時打破了循環,而不是像.map那樣繼續),一旦你有索引可以覆蓋對象直接使用它的索引。確保你不會改變redux狀態,如果你想像這樣指定你需要在克隆上工作:clonedArray[foundIndex] = action.payload;

+0

我選擇這個作爲我仍然需要這種格式和它的作品答案!只是一個簡短的問題,我用你的映射的例子,它的工作原理是完美的,但你會建議使用lodash,因爲這需要瀏覽器的支持? – lost9123193

+0

這確實取決於你需要支持哪些瀏覽器。 Array.map支持IE9 +以及Chrome/SafariFF/Opera。所以,除非你有特定的瀏覽器要求支持IE8,否則你應該對array.map很好。要獲得完整的瀏覽器支持和舊版瀏覽器的polyfill,請參閱MDN頁面:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map。 –

1

這是一個很好的候選數據規範化。如果您在將數據存儲到狀態樹之前對數據進行規範化,則可以有效地用新數據替換數據。

這個例子是直接從Normalizr

[{ 
    id: 1, 
    title: 'Some Article', 
    author: { 
    id: 1, 
    name: 'Dan' 
    } 
}, { 
    id: 2, 
    title: 'Other Article', 
    author: { 
    id: 1, 
    name: 'Dan' 
    } 
}] 

可以歸這個way-

{ 
    result: [1, 2], 
    entities: { 
    articles: { 
     1: { 
     id: 1, 
     title: 'Some Article', 
     author: 1 
     }, 
     2: { 
     id: 2, 
     title: 'Other Article', 
     author: 1 
     } 
    }, 
    users: { 
     1: { 
     id: 1, 
     name: 'Dan' 
     } 
    } 
    } 
} 

什麼是標準化的優勢?

你可以提取你想要的狀態樹的確切部分。

例如 - 您有一個包含有關文章信息的對象數組。如果你想從數組中選擇一個特定的對象,你必須遍歷整個數組。最糟糕的情況是所需的對象不在數組中。爲了克服這個問題,我們對數據進行標準化。

要正常化數據,請將每個對象的唯一標識符存儲在單獨的數組中。我們稱這個數組爲results

result: [1, 2, 3 ..]

和對象陣列轉換成與鍵作爲id的對象(見第二片段)。將該對象稱爲entities

最終,要訪問與id 1的對象,只需執行此操作即可 - entities.articles["1"]

如果你想用新的數據來代替舊的數據,你可以做到這 -

entities.articles["1"] = newObj;

0

陣列的使用本地拼接方法:

/*Find item index using lodash*/ 
var index = _.indexOf(currentPeople, _.find(currentPeople, {id: 1})); 

/*Replace item at index using splice*/ 
arr.splice(index, 1, {id:1, name:'Mark', email:'[email protected]'}); 
+0

對於讀者來說應該注意的是,在Redux中,.splice()應該以不改變狀態但返回新狀態的方式在數組副本上完成。有關此處更多信息,請訪問:http://redux.js.org/docs/Troubleshooting.html –