UseState 总是显示以前的值[重复]

Posted

技术标签:

【中文标题】UseState 总是显示以前的值[重复]【英文标题】:UseState shows previous value always [duplicate] 【发布时间】:2020-06-11 18:42:27 【问题描述】:

这是所有新反应开发人员中的一个流行问题,但不知何故我无法理解可用解决方案背后的逻辑。我正在尝试使用钩子更新状态变量并尝试读取更新后的值,但它总是返回以前的值而不是新值。下面是我的代码执行顺序。

onClick=setTransactionAccountId

单击按钮时,它会执行以下代码并更新状态,但console.log 显示旧值。

const [accountId, setAccountId] = useState(0);

const setTransactionAccountId = e => 
  console.log("Clicked ID:", e.currentTarget.value);
  setAccountId(e.currentTarget.value);
  console.log("accountId:", accountId);
;

控制台日志:

    第一次按钮点击:

点击的 ID:0 帐号:0

    第二次按钮点击:

点击的 ID:1 帐号:0

谁能告诉我这种行为背后的原因以及如何解决它。

【问题讨论】:

【参考方案1】:

accountId 不会在此渲染中更新。您必须等待 下一个 渲染才能更新。 accountId 仅在调用 useState 时填充在函数组件的顶部。你在渲染的中间。如果您需要实际值,请继续将其从e.currentTarget.value 中提取出来。

【讨论】:

我只想将 accountId 作为 props 传递给另一个组件,因此我对其进行了更新,因此,根据我的理解,通过阅读您的评论,我可以随时将 accountId 作为 props 传递,之后将具有最新值按钮单击,但它只是呈现旧值。我的理解正确吗?【参考方案2】:

来自react docs

React 可以将多个 setState() 调用批处理到单个更新中 性能。

因为 this.props 和 this.state 可能是异步更新的,所以你 不应依赖它们的值来计算下一个状态。

状态更新可能是批量和异步更新的,因此在调用 console.log() 时状态可能尚未更新。您将在下次调用 useEffect 挂钩时获得保证的更新结果。

【讨论】:

你的意思是useEffect会解决这个问题? 是的,添加 useEffect(() => ,[])。在 useEffect 的依赖数组中放入你的 state 变量所以 useEffect(() => ,[accountId]) 这将使 useEffect 在你的 accountId 状态更新后运行,从而更新你的屏幕【参考方案3】:

这是因为setState 是异步的。在状态更新之前执行console.log('accountId:', accountId) 仍会为您提供之前的状态值。如果添加 async/await,应该可以解决问题。

const setTransactionAccountId = async (e) => 
    console.log('Clicked ID:', e.currentTarget.value)
    await setAccountId(e.currentTarget.value)
    console.log('accountId:', accountId)

【讨论】:

setAccountId 不返回承诺。因此,在这种情况下,这是一个非常糟糕的竞争条件。它也完全没用,因为你已经有了 accoundId 的值,因为你刚刚设置了它,e.currentTarget.value 是的,我同意 @EmileBergeron 的观点,我尝试了 Andrea 分享的解决方案,但我确实看到旧值打印在控制台中。

以上是关于UseState 总是显示以前的值[重复]的主要内容,如果未能解决你的问题,请参考以下文章

React useState总是落后1步[重复]

在异步函数中正确使用 useEffect 和 useState [重复]

useState 函数没有立即更新[重复]

如何在反应中使用带有useState钩子的回调[重复]

useState 数组在创建重复项时未正确更新

useState和useEffect