这是我的州的例子:
const INITIAL_STATE = {
contents: [ {}, {}, {}, etc.. ],
meta: {}
}
我需要能够以某种方式替换内容数组中的项目,知道它的索引,我试过:
return {
...state,
contents: [
...state.contents[action.meta.index],
{
content_type: 7,
content_body: {
album_artwork_url: action.payload.data.album.images[1].url,
preview_url: action.payload.data.preview_url,
title: action.payload.data.name,
subtitle: action.payload.data.artists[0].name,
spotify_link: action.payload.data.external_urls.spotify
}
}
]
}
其中action.meta.index
是我希望用另一个内容对象替换的数组项的索引,但我相信这只是将整个数组替换为我正在传递的这个对象。我还想过使用.splice()
,但这会改变数组吗?
答案 0 :(得分:15)
请注意,Array.prototype.map()
(docs)不会改变原始数组,因此它提供了另一种选择:
const INITIAL_STATE = {
contents: [ {}, {}, {}, etc.. ],
meta: {}
}
// Assuming this action object design
{
type: MY_ACTION,
data: {
// new content to replace
},
meta: {
index: /* the array index in state */,
}
}
function myReducer(state = INITIAL_STATE, action) {
switch (action.type) {
case MY_ACTION:
return {
...state,
// optional 2nd arg in callback is the array index
contents: state.contents.map((content, index) => {
if (index === action.meta.index) {
return action.data
}
return content
})
}
}
}
答案 1 :(得分:12)
只是建立@ sapy的答案,这是正确的答案。我想向您展示如何在不改变状态的情况下更改Redux中数组内对象属性的另一个示例。
我的州里有一个source.filter()
.do()
.subscribe()
数组。每个orders
都是一个包含许多属性和值的对象。但是,我只想更改order
属性。所以像这样的事情
note
例如let orders = [order1_Obj, order2_obj, order3_obj, order4_obj];
所以在我的Reducer中,我有以下代码:
order3_obj = {note: '', total: 50.50, items: 4, deliverDate: '07/26/2016'};
基本上,你正在做以下事情:
1)在return Object.assign({}, state,
{
orders:
state.orders.slice(0, action.index)
.concat([{
...state.orders[action.index],
notes: action.notes
}])
.concat(state.orders.slice(action.index + 1))
})
order3_obj
2)使用三点[order1_Obj, order2_obj]
点差运算符和您想要更改的特定属性(即order3_obj
)
...
进行Concat(即加入)
3)使用note
和.concat
结尾.slice
的其余订单数组中的Concat,这是.concat(state.orders.slice(action.index + 1))
之后的所有内容(在这种情况下为order3_obj
是剩下的唯一一个。)
答案 2 :(得分:5)
Splice
改变您需要使用的数组Slice
。而且你还需要concat
切片。
return Object.assign({}, state, {
contents:
state.contents.slice(0,action.meta.index)
.concat([{
content_type: 7,
content_body: {
album_artwork_url: action.payload.data.album.images[1].url,
preview_url: action.payload.data.preview_url,
title: action.payload.data.name,
subtitle: action.payload.data.artists[0].name,
spotify_link: action.payload.data.external_urls.spotify
}
}])
.concat(state.contents.slice(action.meta.index + 1))
}