Javascript 状态克隆过早更新
我写了一个非常简单的程序来强调我面临的一个问题。我现在有一个对象数组,每个对象都有一个序列号。单击按钮后,第一个对象的序列号将更新为增加1 在我的程序中,我有几个控制台日志来突出我的问题。首先,我初始化了状态以包含对象数组。然后,我创建了该状态的克隆,以便可以对其进行修改,然后使用克隆(修改)对象重新设置该状态 我的计划如下: App.tsxJavascript 状态克隆过早更新,javascript,reactjs,typescript,react-native,react-hooks,Javascript,Reactjs,Typescript,React Native,React Hooks,我写了一个非常简单的程序来强调我面临的一个问题。我现在有一个对象数组,每个对象都有一个序列号。单击按钮后,第一个对象的序列号将更新为增加1 在我的程序中,我有几个控制台日志来突出我的问题。首先,我初始化了状态以包含对象数组。然后,我创建了该状态的克隆,以便可以对其进行修改,然后使用克隆(修改)对象重新设置该状态 我的计划如下: App.tsx import {useState} from 'react'; function reorder(questionData: Array<any&
import {useState} from 'react';
function reorder(questionData: Array<any>, count: number) {
let finalQuestions = JSON.parse(JSON.stringify(questionData))
console.log("finalQuestions before changes: ", finalQuestions)
finalQuestions[0]['sequence'] = count
return finalQuestions
}
function App() {
const [questions, setQuestions] = useState([
{
sequence: 1
},
{
sequence: 2
},
{
sequence: 3
}
])
const [count, setCount] = useState(4)
function change(questions: Array<any>, count: number) {
console.log("questions before changes: ", questions)
const finalQuestions = reorder(questions, count)
setQuestions(finalQuestions)
setCount(count+1)
console.log("finalQuestions after changes: ", finalQuestions)
}
return (
<div>
<button onClick={() => change(questions, count)}>Click</button>
<h1>Hello World</h1>
</div>
)
}
export default App
console.log(“更改后的问题:”,questions)
显示原始数据集,而不是修改后的数据集,这是我在setQuestions(finalQuestions)
之后所期望的(请参见下面的屏幕截图)。如何及时记录该时刻的实际状态
跟踪值更改后,这是例外结果,您可以正确执行,但只缺少一件事,他们可能在控制台日志的浏览器上保存引用时出现错误,它将在浏览器日志中打印新值,因为每个对象都是打印的,并且具有与您的案例类似的序列,以便可以查看真实值,只需输入控制台的代码,即可使用以下语法:
console.log(
"finalQuestions before changes: ",
JSON.parse(JSON.stringify(finalQuestions))
);
你们必须把它直接放在控制台中,而不是保存在变量中
另外,我认为这将有助于您发现这种情况。这里发生的是console.log是一个异步函数,它将存储对数组的引用,并且在打印出已更改的存储对象时。这可能因您使用的devtool而异 更多信息请点击此处:
控制台日志使用对象的引用,因此当对象发生更改时,它将更新该值 请尝试下面的代码
console.log("finalQuestions before changes: ",JSON.stringify(finalQuestions));
谢谢你!我编辑了我的答案,其中有一个关于原始状态的类似问题,即控制台日志记录不正确(我相信)。您能看一下吗?不客气,现在这是例外的结果,因为quastions参数现在没有更新,您是setQuestions,这是真的,但react仍然没有重新渲染,它将在下一次单击时重新渲染…再次感谢您。因此,即使它显示的是“旧”数据,因为它尚未重新呈现,但数据本身实际上已更新?谢谢!我编辑了我的答案,其中有一个关于原始状态的类似问题,即控制台日志记录不正确(我相信)。请看一下好吗?同样,setQuestions是异步的,这就是为什么要打印旧值。这里我可能错了,但是由于javascript是单线程的,所以React首先需要在任何状态更新之前完成整个函数的运行。因此,在整个功能未完成之前,您仍将保留旧的问题值。再次感谢您!这是有道理的,与另一个答案完全一致。我接受另一个正确答案的唯一原因是因为他先回答了。两个答案都是一样的。虽然此链接可以回答问题,但最好在此处包含答案的基本部分,并提供链接供参考。如果链接页面发生更改,则仅链接的答案可能无效-
console.log("finalQuestions before changes: ",JSON.stringify(finalQuestions));