Я уверен, что это просто мое непонимание React, но я пытаюсь обновить компонент после обновления состояния (что происходит асинхронно).
const [appState, setAppState] = useState({
countries: null,
languages: null
})
useEffect(() => {
const languageURL = `//localhost:8080/languages`,
countryURL = '//localhost:8080/countries';
axios.get(languageURL, {
headers: {'Access-Control-Allow-Origin': '*'}
})
.then((langResponse) => {
const languages = langResponse.data.map(l => ({
value: l.id,
label: l.language + " (" + l.code + ")"
}))
setAppState({languages: languages});
console.log("updating languages");
return languages;
}, (error) => {
console.log(error)
}
);
axios.get(countryURL, {
headers: {'Access-Control-Allow-Origin': '*'}
})
.then((countryResponse) => {
const countries = countryResponse.data.map(l => ({
value: l.id,
label: l.name + " (" + l.code + ")"
}))
setAppState({countries: countries});
console.log("updating countries");
return countries;
}, (error) => {
console.log(error)
}
);
}, [setAppState]);
Мой компонент выглядит так (у меня по одному на каждый набор объектов):
<Select
options={appState.countries}
isSearchable
/>
Я убедился, что данные поступают и соответствуют формату. Проблема, по-видимому, в том, что каждый компонент не отрисовывается при обновлении предоставленного объекта состояния - только один принимает изменения. Также кажется, что одно из них разрешится первым - другое пусто. Это почти противоположно этому вопросу - они обновляются немедленно, < em> до разрешения другого набора.
Unlike the setState method found in class components, useState does not automatically merge update objects. You can replicate this behavior by combining the function updater form with object spread syntax:
reactjs.org/docs/hooks-reference.html#usestate - person Aprillion   schedule 04.09.2020{languages: languages}
, тогда у него больше не будет записиcountries
, и наоборот. Обычно для них используется отдельныйuseState
, а не тот, который содержит и то, и другое. - person Guy Incognito   schedule 04.09.2020useState
работает немного иначе, чем обычное состояние реакции. В определенной степени использование одного объекта для нескольких значений состояния является антипаттерном. Если у вас есть отдельные жизненные циклы для разных обновлений состояния (два значения не зависят друг от друга, как они показаны здесь), проще использовать 2 разных вызоваuseState
. В вашем случае один для языков и один для стран. Исключением может быть ситуация, когда вам нужно передать весь объект appState. В этом случае также рассмотрите шаблон редуктора. - person Garrett Motzner   schedule 04.09.2020