#reactjs #setstate
#reactjs #setstate
Вопрос:
Я пытаюсь выполнить последующие вызовы API, чтобы получить информацию о некоторых финансовых индексах.. После каждого вызова я хочу обновить de indexObject, чтобы он содержал все данные из всех индексов, которые я сохранил в массиве индексов. Проблема в том, что каждый раз, когда вызывается setIndexObject, он перезаписывает объект, теряя предыдущее значение, даже когда я использую оператор распространения.
const [indexObject, setIndexObject] = useState({});
const indexes = [
"^GDAXI",
"^BVSP",
"^NDX",
"^DJI",
"^GSPC",
"^IBEX",
"^HSI",
"^BSESN",
"^FTSE",
];
useEffect(() => {
indexes.forEach((index) => {
const options = {
method: "GET",
url:
"https://apidojo-yahoo-finance-v1.p.rapidapi.com/stock/v2/get-summary",
params: { symbol: `${index}`, region: "US" },
headers: {
"x-rapidapi-key":
"----",
"x-rapidapi-host": "apidojo-yahoo-finance-v1.p.rapidapi.com",
},
};
axios
.request(options)
.then(function (response) {
setIndexObject({
...indexObject,
[index]: {
value: response.data.price.regularMarketPrice.fmt,
variation: response.data.price.regularMarketChangePercent.fmt,
},
});
})
.catch(function (error) {
console.error(error);
});
});
}, []);
Это то, чего я пытаюсь достичь:
{
A:{
value:,
variation:,
},
B:{
value:,
variation,
}
}
Спасибо за помощь!
Комментарии:
1. Если вы добавляете и удаляете подобные объекты подобным образом, не будет ли массив объектов лучшим типом данных для вашего состояния?
2. При использовании текущего состояния для обновления состояния всегда используйте версию обратного
setState
вызова . Кроме того, является ли вызов axios в auseEffect
?3. что такое индекс и как вы его обновляете? кажется, что индекс prop не меняется
4. могу ли я узнать, откуда это [
index
] ? и как вы называете этот запрос axios (нажатие кнопки или useffect или что)?5. Исходное значение indexObject фиксируется закрытием. Используйте форму обратного вызова setState, упомянутую выше, чтобы получить текущее значение при попытке обновления.
Ответ №1:
Проблема здесь в том, что вы зацикливаете запрос, в то время setState
как он не синхронен. Лучше сначала заполнить все данные, а затем установить состояние после этого.
const [indexObject, setIndexObject] = useState({});
const handleFetchData = async () => {
const indexes = [
"^GDAXI",
"^BVSP",
"^NDX",
"^DJI",
"^GSPC",
"^IBEX",
"^HSI",
"^BSESN",
"^FTSE",
];
const resultData = {};
for(const index of index) {
const response = await axios.request(); // add your own request here
resultData[index] = response;
}
return resultData;
}
useEffect(() => {
handleFetchData().then(data => setIndexObject(data));
}, []);
почему я использую for of
? потому forEach
что или .map
не может ожидать асинхронного цикла.
Или, если вы хотите получить все данные одновременно, вы можете рассмотреть возможность использования Promise.all
Комментарии:
1. Спасибо! Он работал с использованием функции обратного вызова setState, но этот способ работает лучше!