是否有可能更新对象的属性与setState?
喜欢的东西:
this.state = {
jasper: { name: 'jasper', age: 28 },
}
我试过:
this.setState({jasper.name: 'someOtherName'});
这:
this.setState({jasper: {name: 'someothername'}})
第一个会导致语法错误,第二个则什么都不做。什么好主意吗?
是否有可能更新对象的属性与setState?
喜欢的东西:
this.state = {
jasper: { name: 'jasper', age: 28 },
}
我试过:
this.setState({jasper.name: 'someOtherName'});
这:
this.setState({jasper: {name: 'someothername'}})
第一个会导致语法错误,第二个则什么都不做。什么好主意吗?
当前回答
试试这个:
const { jasper } = this.state; //Gets the object from state
jasper.name = 'A new name'; //do whatever you want with the object
this.setState({jasper}); //Replace the object in state
其他回答
第一种情况确实是语法错误。
因为我看不到组件的其余部分,所以很难理解为什么要在这里的状态中嵌套对象。在组件状态下嵌套对象不是一个好主意。尝试将初始状态设置为:
this.state = {
name: 'jasper',
age: 28
}
这样,如果你想要更新名称,你可以调用:
this.setState({
name: 'Sean'
});
这能达到你的目标吗?
对于更大、更复杂的数据存储,我会使用Redux之类的东西。但这要高级得多。
关于组件状态的一般规则是只使用它来管理组件的UI状态(例如,活动,计时器等)。
看看这些参考资料:
https://facebook.github.io/react/docs/react-component.html#state https://facebook.github.io/react/docs/state-and-lifecycle.html
这个设置对我来说很管用:
let newState = this.state.jasper;
newState.name = 'someOtherName';
this.setState({newState: newState});
console.log(this.state.jasper.name); //someOtherName
舰队指挥官:样品
const [formData, setformData] = useState({
project_admin_permissions: {
task_forms: false,
auto_assign_rules: false,
project_notes: true,
alerts: false,
update_criteria: true,
project_flow: false,
reports: false,
}
})
const handleChangeCheckBox = (e) => {
setformData({
...formData, project_admin_permissions: { ...formData.project_admin_permissions, [e.target.name]: e.target.checked }
})
}
有多种方法可以做到这一点,因为状态更新是一个异步操作,所以要更新状态对象,我们需要使用setState的updater函数。
1-最简单的一个:
首先创建一个jasper的副本,然后做修改:
this.setState(prevState => {
let jasper = Object.assign({}, prevState.jasper); // creating copy of state variable jasper
jasper.name = 'someothername'; // update the name property, assign a new value
return { jasper }; // return new object jasper object
})
而不是使用Object。我们也可以这样写:
let jasper = { ...prevState.jasper };
2-使用扩展语法:
this.setState(prevState => ({
jasper: { // object that we want to update
...prevState.jasper, // keep all other key-value pairs
name: 'something' // update the value of specific key
}
}))
注意:对象。assign和Spread Operator只创建浅拷贝,所以如果你定义了嵌套对象或对象数组,你需要一种不同的方法。
更新嵌套状态对象:
假设你已经将state定义为:
this.state = {
food: {
sandwich: {
capsicum: true,
crackers: true,
mayonnaise: true
},
pizza: {
jalapeno: true,
extraCheese: false
}
}
}
更新比萨饼对象的extraCheese:
this.setState(prevState => ({
food: {
...prevState.food, // copy all other key-value pairs of food object
pizza: { // specific object of food object
...prevState.food.pizza, // copy all pizza key-value pairs
extraCheese: true // update value of specific key
}
}
}))
更新对象数组:
让我们假设你有一个todo应用程序,你正在以这样的形式管理数据:
this.state = {
todoItems: [
{
name: 'Learn React Basics',
status: 'pending'
}, {
name: 'Check Codebase',
status: 'pending'
}
]
}
要更新任何todo对象的状态,在数组上运行一个map并检查每个对象的某个唯一值,如果condition=true,则返回具有更新值的新对象,否则返回相同的对象。
let key = 2;
this.setState(prevState => ({
todoItems: prevState.todoItems.map(
el => el.key === key? { ...el, status: 'done' }: el
)
}))
建议:如果object没有唯一值,请使用数组索引。
同样,按照Alberto Piras解决方案,如果你不想复制所有的“state”对象:
handleChange(el) {
let inputName = el.target.name;
let inputValue = el.target.value;
let jasperCopy = Object.assign({}, this.state.jasper);
jasperCopy[inputName].name = inputValue;
this.setState({jasper: jasperCopy});
}