我有一个存储在状态中的项目集合:
this.state = {
items: [
{ name: "foo", description: "a foo", index: 0 },
{ name: "bar", description: "a bar", index: 1 },
{ name: "herp", description: "a herp", index: 2 },
{ name: "derp", description: "a derp", index: 3 }
]
};
index
属性表示集合中每个项目的顺序位置。有时我需要重新订购这些元素。例如,“derp”可能需要移到前面,因此其他项的索引需要更新:
{ name: "derp", description: "a derp", index: 0 },
{ name: "bar", description: "a bar", index: 1 },
{ name: "herp", description: "a herp", index: 2 },
{ name: "foo", description: "a foo", index: 3 }
我目前正在使用 immutability-helper
包中的 update
更新状态。但是,我确信这不是正确的方法(尽管它有效):
// originalIndex is a variable holding the original index
// newIndex is a variable holding the new index
// initialise updatedItems so we can update within the loop
let updatedItems = update(this.state.items, { [originalIndex]: {'index': {$set: newIndex}}});
for (var i = newIndex; i < this.state.items.length; i++) {
if (i !== originalIndex) {
updatedItems = update(updatedItems, { [i]: {'index': {set$: parseInt(this.state.items[i].index) + 1}}});
}
}
这感觉像是一次大规模的黑客攻击。
我的问题是,是否可以使用条件逻辑调用更新,因此可以用一次更新调用来替换此循环吗?
最佳答案
假设我们从每个项目中提取 index
属性,您可以像这样创建新列表:
const items = this.state.items.slice();
const value = items[oldIndex];
items.splice(oldIndex, 1); // remove the one you want to move
items.splice(newIndex, 0, value); // add it back to the desired index
this.setState({ items });
也就是说,使用 slice 制作列表的(浅)副本,然后使用 splice 交换元素。
由于您一次只移动一个元素,因此可以使用以下方法保存一行:
const [value] = items.splice(oldIndex, 1);
这会将 splice
返回的数组的第一个元素分配给 value
。
如果你想保留索引
(为什么?),那么你需要重新分配索引:
this.setState({ items: items.map((item, index) => ({ ...item, index })) });
关于javascript - 如何有条件地更新 React 中集合中项目的属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44806299/