问题描述
我正在尝试使用本地存储在React中创建一个非常基本的todo应用程序,并且正在为我的数据使用对象数组。这似乎可以很好地加载信息,但是无论我做什么,我似乎都无法更新本地存储。
我开始回溯,发现在执行handleSave
函数之后,如果我管理日志this.state.todoData
,则会得到正确的更新值。如果立即在该控制台日志之后,我尝试记录JSON.stringify(this.state.todoData)
,它将以字符串形式带回旧数据,而不是带回更新数据。甚至在我对本地存储执行任何操作之前。
我终生无法理解为什么控制台日志记录this.state.todoData
与JSON.stringify(this.state.todoData)
会给我带来不同的数据集。
这是我的handleSave函数:
handleSave (idNum,title,due,description) {
this.setState(prevState => ({
todoData: prevState.todoData.map(obj =>
obj.id === idNum
? Object.assign(obj,{
inEditMode: false,title: title,due: due,description: description
})
: obj
)
}))
console.log(this.state.todoData)
console.log(JSON.stringify(this.state.todoData))
}
解决方法
由于状态不会立即更新,因此您应该在状态成功完成后更新/记录值,例如在setState函数的回调中
this.setState(prevState => ({
todoData: prevState.todoData.map(obj =>
obj.id === idNum ?
Object.assign(obj,{
inEditMode: false,title: title,due: due,description: description
}) :
obj
)
}),() => {
console.log(this.state.todoData)
console.log(JSON.stringify(this.state.todoData))
})
,
this.state.todoData
是对象。通过引用传递的console.log
显示了这一点。如果引用的对象发生了变化,那么控制台记录的对象也会发生变化。
但是,另一方面,当u JSON.stringify
时,它成为按值传递的字符串。因此,它不会改变,
const Obj = {
a: 1,b: 58,};
console.log(Obj);
Obj.a = 484151
console.log(Obj);
他们两个都记录相同的东西
请参见console.log() shows the changed value of a variable before the value actually changes
,(代表问题作者发布解决方案以将其移至答案空间)。
已解决!我必须创建一个新的回调函数并将其作为参数传递给setState
。我没有意识到setState不会立即更新,因此总是感到“落后一步”。
更新的代码:
this.setState(
prevState => ({
todoData: prevState.todoData.map(obj =>
obj.id === idNum
? Object.assign(obj,{
inEditMode: false,description: description
})
: obj
)
}),this.updateLocalStorage
)
}
和updateLocalStorage
函数:
updateLocalStorage () {
const newState = JSON.stringify(this.state.todoData)
localStorage.setItem('todoDataString',newState)
}