#reactjs #typescript #promise #axios
Вопрос:
У меня проблема с циклом на оси GET запроса, и я не могу понять, почему.
const [ state, setState ] = useState<any[]>([]);
ids.forEach((id) => {
getData(id)
.then((smth: Map<string, any>[]) => getNeededData(smth, id));
});
console.log(JSON.stringify(state));
и getData (getNeededData-это только выбор параметров):
export const getData= async (id: string) => {
const response = await Axios.get(`/rest/${id}`)
.then((res: { data: any; }) => res.data);
return response;
};
У меня должно быть 2 ответа (это 2 идентификатора в переменной «идентификаторы»), но у меня есть первый, второй, первый, второй, первый, и это в цикле.
Почему это так работает?
Что я могу изменить, чтобы исправить это?
Комментарии:
1. Вы хотите, чтобы эти запросы выполнялись последовательно или параллельно?
2. Это запрос максимум на 5, так что это не большая разница, но мне любопытно, как переключаться между последовательным и параллельным? 🙂
Ответ №1:
Поместив это forEach
на верхний уровень функции компонента, вы запускаете его каждый раз, когда функция вызывается с помощью React, чтобы отобразить ее содержимое, что происходит при изменении состояния. Код, который вы показали, не задает состояние, но я предполагаю, что это делает ваш настоящий код.
Чтобы сделать это только при первом монтировании компонента, оберните его useEffect
обратным вызовом с пустым массивом зависимостей:
const [ state, setState ] = useState<any[]>([]);
useEffect(() => {
ids.forEach((id) => {
getData(id)
.then(/*...*/);
});
}, []);
Если все результаты собираются в state
массив, вы, вероятно, захотите использовать map
и Promise.all
объединить их все и выполнить с ними одно изменение состояния, например:
const [ state, setState ] = useState<any[]>([]);
useEffect(() => {
Promise.all(
ids.map((id) => {
return getData(id).then(/*...*/);
})
)
.then(allResults => {
// Use `allResults` to set state; it will be an array in the same order
// that the `id` array was in
})
.catch(error => {
// handle/report error
});
}, []);