2017-07-29 63 views
1

我有一个看起来像这样的商店,一个数组中携带数组的3个对象。如何在携带索引1和2的第一个和第二个对象之间添加对象?如何在减速器中添加对象?

{ 
    object: [ 
    { 
     "index": 1, 
     "title": "title", 
     "caption": "caption", 
    }, 
    { 
     "index": 2, 
     "title": "title", 
     "caption": "caption", 
    }, 
    { 
     "index": 3, 
     "title": "title", 
     "caption": "caption", 
    }, 
    ] 
} 

愿有这样最终输出点击一个按钮,通过在1

{ 
    object: [ 
    { 
     "index": 1, 
     "title": "title", 
     "caption": "caption", 
    }, 
    { 
     "index": 2, 
     "title": "NEW", 
     "caption": "NEW", 
    }, 
    { 
     "index": 3, 
     "title": "title", 
     "caption": "caption", 
    }, 
    { 
     "index": 4, 
     "title": "title", 
     "caption": "caption", 
    }, 
    ] 
} 

我可以使用以下代码通过行动改变的索引值的索引值之后,但如何在对象1和对象2之间添加另一个新对象,并同时更改索引值?

switch (action.type) { 
    case ADDCOMPONENT: 
    return { 
     ...state, 
     object: state.object.map(component => 
      (component.index > action.index ? 
      { ...component, index: component.index + 1 } : component)), 
    }; 
+0

你问的是如何改变你的商店的状态?或者如何操作可以从存储中获得的数据,并在特定索引处插入并将对象插入到数组中? –

回答

1
smth.object.splice(index, 0, item); 

而且不守项指数为字符串。您可以轻松地得到阵列项目的位置,然后加1的值

1
state.object.splice(component.index, 0, component); 

应该做的伎俩

1

store的形状是由你所有的减速机的组合创建。您要更新商店的数据应该在您的应用程序中创建,然后通过dispatch(action)发送给您的减速器。 reducer获取有关action的信息并相应地更新您的状态。如果要将对象添加到数组中,则可以使用Array.prototype.splice(),如下所示:myArray.splice(startIndex, 0, itemsToInsert, ...)

总之,不要在你的减速器中添加对象。在发送动作之前,将其添加到您在动作中发送的数据中。

如果您希望能够插入东西到一个数组中,并没有发生变异,您也应该考虑使用的功能像在这个片段:

function nonMutatingArrayInsert(array, index, insert) { 
 
\t // return array if index is outside range of array 
 
     if (index < 0 || index > array.length - 1) return array; 
 

 
     // ensure insert is array for concat purposes 
 
     let _insert = Array.isArray(insert) ? insert : [ insert ]; 
 

 
\t // handle 0 index insert 
 
\t if (index === 0) { return [ ..._insert, ...array ]; } 
 

 
\t // handle end of array insert 
 
\t if (index === array.length) { return [ ...array, ..._insert ] } 
 

 
\t // handle everyhing else 
 
\t const before = array.slice(0, index); 
 
\t const after = array.slice(index, array.length); 
 

 
\t // return new non-mutated array 
 
\t return [ ...before, ..._insert, ...after ]; 
 
} 
 

 
let myArray = [ "one", "four" ]; 
 

 
let newArray = nonMutatingArrayInsert(myArray, 1, ["two", "three"]); 
 

 
console.log("myArray:\n", myArray); 
 
console.log("newArray:\n", newArray);

+0

感谢您的提示。已经从Reducer中移出代码。 –

1

的其他答案似乎错过了你需要增加数组中其他对象索引的观点。我会分两步来处理:首先添加新对象splice,然后循环并递增所有后续索引。

var index = 1; 
state.object.splice(index, 0, new_component); //Insert the new object 

//Starting where you inserted, add one to all later components 
for (var i = index +1; i < state.object.length; i++) { 
    state.object[i].index ++; 
} 

在此之后,state拥有你想要的值。

但是,我鼓励您考虑一下对象是否真的需要知道它们在数组中的位置。根据我的经验,任何需要访问对象的代码都能够知道它们在数组中的位置。

0

所有答案的作品,但是为了不改变数组,我已经使用了下面的代码。

切片数组之前,并插入新的对象之间。

let newObject = state.portfolio.components.slice(0, action.index); 
    newObject = newObject.concat(NEWOBJECT); 
    newObject = newObject.concat(state.portfolio.components.slice(action.index)); 

    for (let i = action.index; i < newComponent.length; i++) { 
    newComponent[i].index = i + 1; 
    } 

用newObject替换对象。

switch (action.type) { 
    case ADDCOMPONENT: 
     return { 
     ...state, 
     object: newObject, 
     }; 

编辑:使用不变性辅助最后用简单的代码没有变异。

return update(state, { 
    portfolio: { 
     object: { 
     $splice: [ 
      [action.index + 1, 0, action.newObject], 
     ], 
     }, 
    } 
    });