我试图通过使用这样的嵌套属性来组织我的状态:
this.state = {
someProperty: {
flag:true
}
}
但是像这样更新状态,
this.setState({ someProperty.flag: false });
是行不通的。怎样才能正确地做到这一点呢?
我试图通过使用这样的嵌套属性来组织我的状态:
this.state = {
someProperty: {
flag:true
}
}
但是像这样更新状态,
this.setState({ someProperty.flag: false });
是行不通的。怎样才能正确地做到这一点呢?
当前回答
我看到每个人都给出了基于类的组件状态更新解决方案,这是预期的,因为他要求,但我试图给钩子相同的解决方案。
const [state, setState] = useState({
state1: false,
state2: 'lorem ipsum'
})
现在,如果你想改变嵌套对象键state1,那么你可以做以下任何一项:
过程1
let oldState = state;
oldState.state1 = true
setState({...oldState);
流程2
setState(prevState => ({
...prevState,
state1: true
}))
我最喜欢过程。
其他回答
There is another option and this works if there are multiple items in the list of objects: copy the object using this.state.Obj to a variable (say temp), use filter() method to traverse through the object and grab the particular element you want to change into one object(name it updateObj) and the remaining list of object into another object(name this as restObj). Now edit the contents of object you want to update creating a new item (say newItem). Then call this.setUpdate() and use spread operators to assing new list of objects to the parent object.
this.state = {someProperty: { flag:true, }}
var temp=[...this.state.someProperty]
var restObj = temp.filter((item) => item.flag !== true);
var updateObj = temp.filter((item) => item.flag === true);
var newItem = {
flag: false
};
this.setState({ someProperty: [...restObj, newItem] });
还有两个选项没有提到:
如果您有深度嵌套的状态,请考虑是否可以重新构造子对象,使其位于根节点。这使得数据更容易更新。 Redux文档中列出了许多方便的库来处理不可变状态。我推荐Immer,因为它允许您以可变的方式编写代码,但在幕后处理必要的克隆。它还会冻结生成的对象,这样以后就不会意外地改变它。
如果你正在使用ES2015,你可以访问Object.assign。您可以使用它来更新嵌套对象。
this.setState({
someProperty: Object.assign({}, this.state.someProperty, {flag: false})
});
您将更新的属性与现有属性合并,并使用返回的对象更新状态。
编辑:将一个空对象作为目标添加到赋值函数中,以确保状态不会像carkod指出的那样直接发生突变。
我知道这是一个老问题,但仍然想分享我是如何做到这一点的。假设构造函数中的状态是这样的:
constructor(props) {
super(props);
this.state = {
loading: false,
user: {
email: ""
},
organization: {
name: ""
}
};
this.handleChange = this.handleChange.bind(this);
}
我的handleChange函数是这样的:
handleChange(e) {
const names = e.target.name.split(".");
const value = e.target.type === "checkbox" ? e.target.checked : e.target.value;
this.setState((state) => {
state[names[0]][names[1]] = value;
return {[names[0]]: state[names[0]]};
});
}
并确保你的输入相应的名称:
<input
type="text"
name="user.email"
onChange={this.handleChange}
value={this.state.user.firstName}
placeholder="Email Address"
/>
<input
type="text"
name="organization.name"
onChange={this.handleChange}
value={this.state.organization.name}
placeholder="Organization Name"
/>
我看到每个人都给出了基于类的组件状态更新解决方案,这是预期的,因为他要求,但我试图给钩子相同的解决方案。
const [state, setState] = useState({
state1: false,
state2: 'lorem ipsum'
})
现在,如果你想改变嵌套对象键state1,那么你可以做以下任何一项:
过程1
let oldState = state;
oldState.state1 = true
setState({...oldState);
流程2
setState(prevState => ({
...prevState,
state1: true
}))
我最喜欢过程。