我正在使用本地反应。假设我处于这种状态:
{
persons: [{
name: "Person",
id: 0,
value: "",
percent: 50,
messed: false
},
{
name: "Person",
id: 1,
value: "",
percent: 50,
messed: false
}]
}
我想更新,例如,id的百分比1.如何使用this.setState
进行更新?我可以每次都深入克隆人物并更新它但我需要做很多次并且人物对象相当大,所以它在性能方面没有效率。
目前我正在做
this.state.persons[id].percent = 0;
this.forceUpdate();
似乎没那么反应。我该怎么做?
答案 0 :(得分:3)
你不应该直接更新状态,因为反应在他们的文档中提到了几次。您可以使用的选项是spread oeprator(或Object.assign):
let newPersonsList = [...this.state.persons];
newPersonsList[2] = {...newPersonsList[2], percent:0};
this.setState({persons:newPersonsList});
注意,扩展运算符在复制数组时只有1级深度,我相信,所以你对所有的人物objets采用相同的引用并将它们放在一个新的数组中。然后,您将创建一个具有更新百分比属性的新对象,并将其指定为替换旧引用。性能方面,这应该很快,因为不会发生广泛的深层复制。
或者,如果您发现自己有很多嵌套对象需要更新,我建议您查看以下库: immutability-helper 。它专门为这种情况而设计。
答案 1 :(得分:1)
你必须更新整个州,与你正在做的非常相似。但是,我建议不要使用this.forceUpdate()
来调用this.setState({ persons: this.state.persons })
。
您可能想要做的是考虑将persons
纳入州内。您可以根据索引为每个键创建一个唯一键。所以,索引是这样的:
const persons = getPersonsData();
this.setState({ persons });
而是做这样的事情:
const persons = getPersonsData();
this.setState(persons.reduce((result, person, index) => Object.assign(result, { [`person${index}`]: person }));
persons.reduce
位将获取您的数组并创建如下对象:
{
person0: {},
person1: {},
person2: {}
}
然后,每个人都会处于平态状态,因此您可以直接更新它。没有太大的区别,但取决于你的用例,可能是值得的。
答案 2 :(得分:0)
我只想使用setState。让React担心性能优化
this.setState(object.assign({}, this.state,
this.state.persons.map(p => {
if (p.id === id) p.percent = 0;
}
)))
答案 3 :(得分:0)
另一种改变状态的方法,但是按人名整理状态可能是更好的选择。
state = {
persons: [{
name: "Person",
id: 0,
value: "",
percent: 50,
messed: false
},
{
name: "Person",
id: 1,
value: "",
percent: 50,
messed: false
}]
}
this.setState(({persons}) => {
persons
.filter(i => i.id === 1)
.map(i => i.percent = 0)
})}