是否可以将对象存储在React组件的状态中?如果是,那么我们如何使用setState
更改该对象中键的值?我认为在语法上不允许写出类似的内容:
this.setState({ abc.xyz: 'new value' });
在类似的路线上,我还有另一个问题:在React组件中有一组变量可以在组件的任何方法中使用它们,而不是将它们存储在一个状态中吗?
您可以创建一个包含所有这些变量的简单对象,并将其放置在组件级别,就像在组件上声明任何方法一样。
很可能遇到这样的情况,即在代码中包含大量业务逻辑,并且需要使用许多变量,这些变量的值由多种方法更改,然后根据这些值更改组件的状态。
因此,不要将所有这些变量保留在状态中,而只保留那些值应直接反映在UI中的变量。
如果这种方法比我在这里写的第一个问题更好,那么我不需要在州内存储一个对象。
答案 0 :(得分:80)
this.setState({ abc.xyz: 'new value' });
语法是不允许的。
你必须传递整个对象。
this.setState({abc: {xyz: 'new value'}});
如果你在abc中有其他变量
var abc = this.state.abc;
abc.xyz = 'new value';
this.setState({abc: abc});
如果他们不依赖this.props和this.state
,你可以拥有普通变量。
答案 1 :(得分:30)
除了kiran的帖子,还有update helper(以前为a react addon)。这可以使用npm install immutability-helper
import update from 'immutability-helper';
var abc = update(this.state.abc, {
xyz: {$set: 'foo'}
});
this.setState({abc: abc});
这将创建一个具有更新值的新对象,其他属性保持不变。当您需要执行诸如推入数组和同时设置其他值之类的操作时,这会更有用。有些人到处使用它,因为它提供了不变性。
如果您这样做,可以使用以下内容来弥补
的性能shouldComponentUpdate: function(nextProps, nextState){
return this.state.abc !== nextState.abc;
// and compare any props that might cause an update
}
答案 2 :(得分:26)
您可以对对象中的先前值使用ES6 spread以避免覆盖
this.setState({
abc: {
...this.state.abc,
xyz: 'new value'
}
});
答案 3 :(得分:14)
Exception in thread "main" java.lang.IllegalAccessError: tried to access class java.lang.AbstractStringBuilder from class stream.CollectCollector
at stream.CollectCollector.lambda$main$0(CollectCollector.java:25)
将无效,因为this.setState({abc: {xyz: 'new value'}});
将被完全覆盖,而不会合并。
这对我有用:
state.abc
除非我正在阅读文档错误,否则Facebook会推荐以上格式。 https://facebook.github.io/react/docs/component-api.html
此外,我想没有变异状态的最直接的方法是使用ES6传播/休息算子直接复制:
this.setState((previousState) => {
previousState.abc.xyz = 'blurg';
return previousState;
});
答案 4 :(得分:5)
尽管可以通过immutability-helper或类似方法完成,但我不想在我的代码中添加外部依赖项,除非我真的需要。当我需要这样做时,我使用Object.assign
。代码:
this.setState({ abc : Object.assign({}, this.state.abc , {xyz: 'new value'})})
也可以在HTML事件属性上使用,例如:
onChange={e => this.setState({ abc : Object.assign({}, this.state.abc, {xyz : 'new value'})})}
答案 5 :(得分:3)
在一行代码中更容易实现
this.setState({object: {...this.state.object, objectVarToChange: newData}})
答案 6 :(得分:1)
如果您想使用功能组件将对象存储在状态中,您可以尝试以下操作。
import React from 'react';
import {useState, useEffect} from 'react';
const ObjectState= () => {
const [username, setUsername] = useState({});
const usernameSet = () => {
const name = {
firstname: 'Naruto',
familyname: 'Uzmaki'
}
setUsername(prevState => name);
}
return(
<React.Fragment>
<button onClick= {usernameSet}>
Store Object
</button>
{username.firstname} {username.familyname}
</React.Fragment>
)
}
export default ObjectState;
如果要将对象添加到预先存在的对象中。
import React from 'react';
import {useState, useEffect} from 'react';
const ObjectState= () => {
const [username, setUsername] = useState({village: 'Konoha'});
const usernameSet = () => {
setUsername((prevState) => {
const data = {
...prevState,
firstname: 'Naruto',
familyname: 'Uzmaki'
}
return data
});
}
return(
<React.Fragment>
<button onClick= {usernameSet}>
Store Object
</button>
{username.village} {username.firstname} {username.familyname}
</React.Fragment>
)
}
export default ObjectState;
P.S. :将组件命名为“对象”会导致“最大调用堆栈大小” 超出错误'。其他名称很好,但出于某种原因,“对象”是 不是。 像下面这样不行。
const Object = () => {
// The above code
};
export default Object;
如果有人知道为什么或如何阻止它,请将其添加到评论中。
答案 7 :(得分:-5)
它对我有用。
_onPress = () => {
this.state.abc.xyz = "new value";
this.setState({});
}
编辑:
_onPress = () => {
let newValue = this.state.abc
newValue.xyz = "new value"
this.setState({abc: newValue });
}