为什么反应钩子值在异步函数中不更新?

时间:2019-12-20 04:30:00

标签: javascript reactjs react-hooks

在运行 run 函数时,我希望 value 变量的值为“ new”,但是即使500毫秒,它仍然保持“ old”状态。为什么会发生这种情况以及如何解决这个问题?

import React, { Component, useState } from "react";
import { render } from "react-dom";

function App() {
  const [value, setValue] = useState('old');

  const run = async() => {
    setValue('new')
    const data = await wait(500)
    console.log(value)
  }

  return (
    <button onClick={run}>
      Run
    </button>
  );
}

render(<App />, document.getElementById("root"));

function wait(ms) {
  return new Promise(resolve => setTimeout(resolve, ms))
}

3 个答案:

答案 0 :(得分:3)

setState异步运行,因此不会立即反映在功能代码块中。您可以尝试使用useEffect来监视状态的变化。

useEffect(() => console.log('value', value), [value])

答案 1 :(得分:0)

在您的情况下,const [value, setValue] = useState('old'); setValue只不过与类Components中的setState相同。因此,由于setState和setValue是异步函数,因此您永远无法预测何时更新值。

因此,您可以在类组件中使用componentDidUpdate,也可以像useEffect这样使用useEffect(() => callFn();, [value])。所以这里的callFn()是一个函数,将在值更新后调用。

希望有帮助。毫无疑问

答案 2 :(得分:0)

好的,这是我想发生的事情: 您单击按钮,它调用您的 run 函数-然后运行函数调用 setState

  • 我认为 setState 应该会导致组件重新呈现 与新值,如果您将其显示在某处,它将立即显示。因此,如果您想立即看到更改,请添加一个显示。
  • setState 之后立即控制台登录 run 函数时,组件尚未重新呈现,这意味着您仍在使用旧值。
  • 重新渲染组件时,您不会看到控制台记录的值,因为没有再次调用 run 函数。单击两次按钮应该会控制台记录新值,因为届时组件将使用新值重新呈现。