useState конфликтует с асинхронными операциями в React - PullRequest
4 голосов
/ 26 сентября 2019

В функциональном компоненте React с хуком useState я не знаю, как выполнить несколько асинхронных операций, не конфликтуя с конечным результатом.

Если исходное состояние является объектом и каждая асинхронная операциявыполняет изменение данного ключа, можно использовать оператор распространения, чтобы установить новое состояние.Пример:

const [oldState, setNewState] = React.useState({ /* something */ });
const asyncOperation = async () => {
   await somethingAsync();
   setNewState({
      ...oldState,
      key: 'newValue',
   });
};

Проблема возникает, когда одновременно выполняется больше этих операций: oldState, используемый во время setNewState, может быть изменен в конце другой асинхронной функции, но некоторые обновлениясостояние может быть потеряно, когда последняя асинхронная операция выполняет его setNewState, поскольку ссылка на oldState может указывать на старую версию переменной.

Вот демонстрационная версия : попробуйте нажатькаждая кнопка в ряду, и, в конце концов, некоторые из них (вероятно) будут по-прежнему загружаться.

Как можно избежать этой проблемы, не оставляя реагирующих хуков?

1 Ответ

4 голосов
/ 26 сентября 2019

Установка состояния имеет первый аргумент, который является предыдущим состоянием.

Для асинхронных операций необходимо использовать предыдущее состояние.

setNewState((previousState) => ({
  ...previousState,
  key: 'newValue',
}));

Здесь oldState есть! = previousState.

...