11

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

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

控制台日志:

  1. 第一个按钮点击:

点击 ID: 0 accountId: 0

  1. 第二个按钮点击:

点击 ID:1 accountId:0

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

4

3 回答 3

7

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

于 2020-02-27T17:19:59.923 回答
3

来自反应文档

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

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

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

于 2020-02-27T17:25:36.517 回答
-1

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

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

于 2020-02-27T17:20:50.733 回答