我有一个处于状态的对象数组:
this.state = {
items: [
{id: 1, someattr: "a string", anotherattr: ""},
{id: 2, someattr: "another string", anotherattr: ""},
{id: 3, someattr: "a string", anotherattr: ""},
]
}
我需要能够根据id属性搜索items数组,然后更新对象属性。
我可以使用id参数在数组上通过filtering
或finding
获取对象。
我遇到的问题是更新阵列,然后更新状态而不会发生变异。
//make sure we're not mutating state directly by using object assign
const items = Object.assign({}, this.state.items);
const match = items.find((item) => item.id === id);
此时我有一个匹配的对象,可以使用对象扩展来更新它的属性:
const matchUpdated = { ...match, someattr: 'a new value'};
我的问题是如何用matchUpdated
更新状态,以便覆盖初始查找操作返回的对象?
答案 0 :(得分:22)
您的更新功能如下所示
updateItem(id, itemAttributes) {
var index = this.state.items.findIndex(x=> x.id === id);
if (index === -1)
// handle error
else
this.setState({
items: [
...this.state.items.slice(0,index),
Object.assign({}, this.state.items[index], itemAttributes),
...this.state.items.slice(index+1)
]
});
}
你就像这样使用它
this.updateItem(2, {someattr: 'a new value'});
总权利?
但是,如果你继续以这种方式构建复杂的应用程序,那么你将会遇到很大的麻烦。您应该真正研究redux或其他更适合解决这些问题的Flux实现。
Redux使用状态缩减器的概念,每个状态缩减器都在应用程序状态的特定片上工作。这样,每次想要影响深层次变化时,您都不必手动挖掘整个状态。
Redux的创作者Dan Abramov已经免费在线提供了两个视频课程。 Dan是一位优秀的老师,在我花了一个下午之后,我对Redux模式感到很自在。
答案 1 :(得分:2)
如果您想使用一个函数,这就是我的方法...
ConceptName auto
函数的第一个输入是项目的ID。
函数的第二个输入是您想要更改的属性。
函数的第三个输入是该属性的新值。
答案 2 :(得分:1)
如果你使用函数式组件和 useState 钩子,你可以很容易地使用 map,只要你不介意替换整个对象
const [items, setItems] = useState ([
{id: 1, someattr: "a string", anotherattr: ""},
{id: 2, someattr: "another string", anotherattr: ""},
{id: 3, someattr: "a string", anotherattr: ""},
])
setItems (
items.map((item) => {
item.id === updatedItem.id? updatedItem: item;
})
);
答案 3 :(得分:0)
您可以遍历状态数组对象的值并替换状态。 在循环中,如果不是全部,您可以决定要应用新值的记录。
this.state = {
items: [
{id: 1, someattr: "a string", anotherattr: ""},
{id: 2, someattr: "another string", anotherattr: ""},
{id: 3, someattr: "a string", anotherattr: ""},
]
}
//答案
const newState = Object.assign({}, this.state);
newState.items.forEach(element => {
element.someattr= "I like it a lot";
});
this.setState(newState);
答案 4 :(得分:-2)
在这样的功能组件中 你必须把它添加到函数中
const [item,setitem]=usestate([{id_1:null},{id_2:null}])
()=> setitems((prev) => { return { ...prev, id_1: "my change value"} })
并像这样使用它
console.log(items.id_1 == "my change value")