UseState всегда показывает предыдущее значение

Это популярный вопрос среди всех новых разработчиков, но почему-то я не могу понять логику имеющихся решений. Я пытаюсь обновить переменную состояния с помощью хуков и пытаюсь прочитать обновленное значение, но всегда возвращает предыдущее значение вместо нового значения. Ниже представлена ​​последовательность выполнения моего кода.

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

может ли кто-нибудь рассказать мне причину такого поведения и как с этим бороться.

3 ответа

accountIdне будет обновлен этот рендер. Вам нужно дождаться следующего рендера, чтобы он обновился. accountId заполняется только в верхней части функционального компонента, когда useStateназывается. Вы в середине рендера. Если вам нужна реальная стоимость, продолжайте вытаскивать ее изe.currentTarget.value.

Из реакционных документов

React может объединять несколько вызовов setState() в одно обновление для повышения производительности.

Поскольку this.props и this.state могут обновляться асинхронно, вам не следует полагаться на их значения при вычислении следующего состояния.

Обновления состояния могут группироваться и обновляться асинхронно, поэтому состояние могло не обновляться при вызове console.log(). Вы получите гарантированно обновленный результат при следующем вызове хука useEffect.

Это потому что 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)
}

Другие вопросы по тегам