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. первое нажатие кнопки:

Идентификатор клика: 0 accountId: 0

  1. нажатие второй кнопки:

Идентификатор клика: 1 accountId: 0

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


person vivek.p.n manu    schedule 27.02.2020    source источник


Ответы (3)


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

person zero298    schedule 27.02.2020
comment
Я просто хочу передать accountId в качестве реквизита другому компоненту, поэтому я обновляю его, поэтому, согласно моему пониманию, прочитав ваш комментарий, я всегда могу пойти и передать accountId в качестве реквизита, который будет иметь последнее значение после нажатия кнопки, но он просто отображает старый ценить. я правильно понимаю? - person vivek.p.n manu; 28.02.2020

Из реагировать на документы

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

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

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

person Hassaan Tauqir    schedule 27.02.2020
comment
вы имеете в виду, что useEffect решит эту проблему? - person vivek.p.n manu; 28.02.2020

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

person Andrea    schedule 27.02.2020
comment
setAccountId не возвращает обещание. Так что это состояние гонки, которое в данном случае действительно плохо. Это также совершенно бесполезно, поскольку у вас уже есть значение accoundId, поскольку вы только что его установили, e.currentTarget.value. - person Emile Bergeron; 27.02.2020
comment
Да, я согласен с @EmileBergeron, и я попробовал решение, которым вы поделились с Андреа, но я вижу, что старое значение печатается в консоли. - person vivek.p.n manu; 28.02.2020