Javascript 状态克隆过早更新

Javascript 状态克隆过早更新,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&

我写了一个非常简单的程序来强调我面临的一个问题。我现在有一个对象数组,每个对象都有一个序列号。单击按钮后,第一个对象的序列号将更新为增加1

在我的程序中,我有几个控制台日志来突出我的问题。首先,我初始化了状态以包含对象数组。然后,我创建了该状态的克隆,以便可以对其进行修改,然后使用克隆(修改)对象重新设置该状态

我的计划如下: App.tsx

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));