Последовательность состояний набора не работает внутри вызова api, почему?

#reactjs #react-hooks

Вопрос:

Я пытаюсь установить два состояния после извлечения некоторых данных из вызова api.

 const [value1, setValue1] = useState();
const [value2, setValue2] = useState();

const getValues = async () => {
await valuesService
  .getValuesFromBackEnd(params)
  .then(data => {
    setValue1(data.value1);
    setValue2(data.value2);
  });
};
 

Используя приведенный выше код, он работает только с setValue1. Если изменить порядок setStates, это работает только для setValue2. Если я добавлю useDispatch перед ними обоими, они будут работать идеально, устанавливая оба состояния. Также отлично работает, если я помещу один из них в функцию setTimeout. Кто-нибудь может объяснить, почему это происходит? Примеры кода, работающего по назначению:

 const [value1, setValue1] = useState();
const [value2, setValue2] = useState();

const getValues = async () => {
await valuesService
  .getValuesFromBackEnd(params)
  .then(data => {
    setValue1(data.value1);
    setTimeout(() => {
       setValue2(data.value2);
    }, 3000);
  });
};
 

или

 const [value1, setValue1] = useState();
const [value2, setValue2] = useState();
const dispatch = useDispatch();

const getValues = async () => {
await valuesService
  .getValuesFromBackEnd(params)
  .then(data => {
    dispatch (something);
    setValue1(data.value1);
    setValue2(data.value2);
  });
};
 

Ответ №1:

Когда у вас есть экземпляры, в которых вы устанавливаете несколько битов состояния одновременно, лучше использовать useReducer вместо setState этого . У Кента Доддса есть отличная статья о различиях.

В конечном счете, дело не в том, что значение 1 и значение 2 не задаются одновременно, а в том, что при использовании useState методов «набора» они на самом деле не обновляются одновременно. Сначала обновляется значение 1, которое запускает повторные вызовы, затем обновляется значение 2, запуская еще один раунд повторных вызовов. При использовании вы useReducer можете обновить оба вместе.