Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/442.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何在React中有条件地更新集合中项的属性?_Javascript_Reactjs - Fatal编程技术网

Javascript 如何在React中有条件地更新集合中项的属性?

Javascript 如何在React中有条件地更新集合中项的属性?,javascript,reactjs,Javascript,Reactjs,我有一个存储在以下状态的项目集合: 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", descrip

我有一个存储在以下状态的项目集合:

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 }
    ]
};
索引
属性表示集合中每个项的顺序位置。有时我需要重新订购这些物品。例如,“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 }
我目前正在使用
不变性助手
包中的
更新
更新状态。然而,我确信这不是正确的方法(尽管它有效):

//originalIndex是一个保存原始索引的变量
//newIndex是保存新索引的变量
//初始化UpdateItems,以便在循环中进行更新
让updateItems=update(this.state.items,{[originalIndex]:{'index':{$set:newIndex}}});
for(var i=newIndex;i
这感觉像是一次大规模的黑客攻击


我的问题是,是否可以使用条件逻辑调用update,因此可以用单个调用update来替换此循环?

为什么不在render()上对项目进行排序:


为什么不在render()上对项目进行排序:


假设我们从每个项目中提取
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);
这将
拼接
返回的数组的第一个元素分配给

如果要保留
索引
(为什么?),则需要重新分配索引:

this.setState({ items: items.map((item, index) => ({ ...item, index })) });

假设我们从每个项目中提取
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);
这将
拼接
返回的数组的第一个元素分配给

如果要保留
索引
(为什么?),则需要重新分配索引:

this.setState({ items: items.map((item, index) => ({ ...item, index })) });

如果
index
真正指的是items数组中的索引,那么将其作为每个对象内部的属性似乎有点不太妥当。@TomFenech也这么说。当一个元素可以被它在数组中的索引直接引用时,在数组中不需要index属性,这实际上是一个很好的观点!我没有想到这一点。因此,如果我们删除
索引
属性,那么每个项目是否仍然是一个具有
名称
属性的对象,或者您现在只是一个字符串列表?@TomFenech每个项目仍然是一个对象。事实上,我只是根据你的回答更新了这个问题。很明显,我把问题简化得太多了。我的实际对象除了索引外还包含4个属性。
index
作为每个对象内部的属性似乎有点不太妥当,如果它真正指的是items数组中的索引。与@TomFenech所说的一样。当一个元素可以被它在数组中的索引直接引用时,在数组中不需要index属性,这实际上是一个很好的观点!我没有想到这一点。因此,如果我们删除
索引
属性,那么每个项目是否仍然是一个具有
名称
属性的对象,或者您现在只是一个字符串列表?@TomFenech每个项目仍然是一个对象。事实上,我只是根据你的回答更新了这个问题。很明显,我把问题简化得太多了。除了索引之外,我的实际对象还包含4个属性。因为JavaScript的
排序
修改了它的接收者,所以此代码将变异
此.state
,React文档强烈警告不要这样做。您可能需要执行
让toDisplay=this.state.items.slice().sort(…)
来操作数组的副本。因为JavaScript的
排序
修改了它的接收器,所以此代码将变异
this.state
,React文档强烈警告不要这样做。您可能需要执行
让toDisplay=this.state.items.slice().sort(…)
来操作数组的副本。谢谢Tom。我同意事后看来,在对象中包含索引是毫无意义的。明天我来试试。谢谢汤姆。我同意事后看来,在对象中包含索引是毫无意义的。我明天给你打一针。