UseState总是显示先前的值

18

这是所有新的React开发者中一个流行的问题,但我不知道可用解决方案背后的逻辑。我正试图使用hooks更新状态变量并尝试读取更新后的值,但它总是返回先前的值而不是新值。以下是我的代码执行顺序。

onClick={setTransactionAccountId}
在按钮点击时,它会执行下面的代码并更新状态,但是console.log显示旧值。

在点击按钮后,执行以下代码并更新状态,但是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);
};

控制台日志:

  1. 第一个按钮点击:

点击的 ID:0 账户 ID:0

  1. 第二个按钮点击:

点击的 ID:1 账户 ID:0

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

3个回答

7

accountId在这个渲染周期内不会被更新,你需要等待下一个渲染周期才能获得更新后的值。在函数组件中调用useState时,accountId只会被填充一次,也就是在函数组件顶部调用该方法时。而此时你正处于渲染过程中,如果需要实际的值,请从e.currentTarget.value中持续获取。


我只想将accountId作为props传递给另一个组件,因此我正在更新它,根据我阅读您的评论的理解,我可以随时传递accountId作为props,这将在按钮单击后具有最新值,但它仍然呈现旧值。我的理解正确吗? - vivek.p.n manu

6

来自React文档

为了性能,React可能会将多个setState()调用批处理成单个更新。

由于this.props和this.state可能会异步更新,因此您不应依赖它们的值来计算下一个状态。

状态更新可能会被批处理并异步更新,因此当console.log()被调用时,状态可能尚未更新。在您下一次调用useEffect hook时,您将获得保证已更新的结果。


你的意思是说 useEffect 可以解决这个问题吗? - vivek.p.n manu
2
是的,在你的程序中加入useEffect(() => { },[])。在useEffect的依赖数组中,放上你的状态变量,比如useEffect(() => { },[accountId])。这样做会使得useEffect在accountId状态更新后运行,从而更新你的屏幕。 - AmandaConda
请为您的方法使用async。 - Salma Gomaa

-2
这是因为 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)
}


3
setAccountId 不会返回 Promise。因此,在这种情况下,这是一个竞态条件,非常糟糕。而且它也完全没有用,因为您已经有了 accountId 的值,即您刚刚设置的 e.currentTarget.value - Emile Bergeron
是的,我同意@EmileBergeron的观点,并尝试了Andrea分享的解决方案,但我在控制台中看到旧值被打印出来。 - vivek.p.n manu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接