假设我有一个Person类:
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
}
然后我以状态实例化一个Person对象:
export default class SomeComponent extends React.Component {
constructor() {
super();
this.state = {
cena: new Person('John Cena', 40)
}
}
render() {
const { name, age } = this.state.cena;
return (
<div>
<p>Name: {name}</p>
<p>Age: {age}</p>
</div>
)
}
}
假设我们有一个按钮,可将Cena的年龄增加一岁。尽管我们只需要更改年龄,但使用全新的Person对象设置状态是否安全?
this.setState(prevState => ({
cena: new Person(prevState.cena.name, prevState.cena.age + 1)
}));
我确实使用Chrome的绘画闪光工具对此进行了测试。当我将this.state.cena
设置为年龄增长的全新Person时,仅重绘了Age段落,Name段落保持不变。
但是,我还是有点担心。我应该依靠React来进行有效的浅表比较,还是应该只手动更改需要更改的内容?
我什至不知道该如何实现。如果我只尝试setState
的年龄,我仍然必须做类似的事情:
this.setState(prevState => ({
cena: { ...prevState, age: prevState.age + 1 }
}));
与通过其构造函数创建新Person完全相同。要仅“有效”更新年龄,我必须将“人”传播到州的第一层。
constructor() {
super();
this.state = {
...new Person('John Cena', 40)
}
}
这很糟糕,因为以后可能需要创建另一个Person。
因此,我将重述我的问题:我应该设置一个全新的对象并依靠React来进行浅层比较吗?
答案 0 :(得分:1)
我应该依靠React来进行有效的浅表比较,还是应该仅手动更改需要更改的内容?
您传递给setState的所有内容都会与当前状态合并。合并之后,如果状态发生了变化,React将重新渲染使用此状态的组件。
这三个示例在功能上都是相同的,您应该使用最容易理解的示例。
通常,您可以依靠它来表现出色。您还可以通过在适当的地方使用PureComponent和/或功能组件来提高性能。
答案 1 :(得分:0)
您的状态将仅存在于组件(SomeComponent)中,除非它通过函数属性发送回。
为什么不采用您最后提出的解决方案,而扩展新的Person实例。 如果看起来很奇怪,请尝试在构造函数之外实例化该类。
示例:
let person = new Person('Name', 40);
this.state = {
...this.person,
};
console.log(this.state); // outputs the instance members
或
let person = new Person('Name', 40);
this.state = {
person: this.person
};
console.log(this.state.person); // outputs the instance members
如果您的组件状态需要存储多个Person实例,则可以将它们存储在数组中:
let personA = new Person('A', 21);
let personB = new Person('B', 25);
this.state = {
persons: [personA, personB]
}
要更新此人,treat the state as if it's immutable:
const persons = this.state.persons.slice() //copy the array
persons[1].name = 'C' //manipulate Person 'B' instance
this.setState({ persons }) //set the new state
答案 2 :(得分:-1)
通常,我不会创建用于存储状态的类对象。为了简单起见,我将状态设置为对象:
3x3
现在,我可以像这样简单地更改状态:
this.state = {
cena: {
name: '',
age: ''
}
}