Вы устанавливаете загруженные рубашки после каждой итерации, так что вы будете получать только последние разрешенные данные обещания, вместо этого извлеките все данные и затем обновите состояние.
Кроме того, отделите свое состояние, одно для загрузки состояние и один для данных.
Вариант 1 с использованием async/await
const recipeId = '15f09b5f-7a5c-458e-9c41-f09d6485940e'
const BASE_URL = 'https://api.print.io/api/v/5/source/api'
const fetchProducts = async () => {
const { data } = await axios.get(`${BASE_URL}/prpproducts/?recipeid=${recipeId}&page=1`)
return data.Products
}
const fetchShirts = async productName => {
const { data } = await axios.get(
`${BASE_URL}/prpvariants/?recipeid=${recipeId}&page=1&productName=${productName}`,
)
return data.Variants
}
const HomePage = props => {
const [isLoading, setIsLoading] = useState(false)
const [shirtList, setShirtList] = useState([])
useEffect(() => {
setIsLoading(true)
const fetchProductShirts = async () => {
const products = await fetchProducts()
const shirts = await Promise.all(
products.map(({ productName }) => fetchShirts(productName)),
)
setShirtList(shirts)
setIsLoading(false)
}
fetchProductShirts().catch(console.log)
}, [])
}
Вариант 2 с использованием необработанных обещаний
const recipeId = '15f09b5f-7a5c-458e-9c41-f09d6485940e'
const BASE_URL = 'https://api.print.io/api/v/5/source/api'
const fetchProducts = () =>
axios.get(`${BASE_URL}/prpproducts/?recipeid=${recipeId}&page=1`)
.then(({ data }) => data.Products)
const fetchShirts = productName =>
axios
.get(
`${BASE_URL}/prpvariants/?recipeid=${recipeId}&page=1&productName=${productName}`,
)
.then(({ data }) => data.Variants)
const HomePage = props => {
const [isLoading, setIsLoading] = useState(false)
const [shirtList, setShirtList] = useState([])
useEffect(() => {
setIsLoading(true)
fetchProducts
.then(products) =>
Promise.all(products.map(({ productName }) => fetchShirts(productName))),
)
.then(setShirtList)
.catch(console.log)
.finally(() => setIsLoading(false)
}, [])
}
Теперь у вас есть состояние isLoading
для состояние загрузки и shirtList
для данных, которые вы можете отобразить, основываясь на этом, как это
return (
<div>
{isLoading ? (
<span>loading...</span>
) : (
// always set a unique key when rendering a list.
// also rethink the prop names
shirtList.map(shirt => <ShirtList key={shirt.id} items={shirt} />)
)}
</div>
)
Ссылки
Promise.all
Promise.prototype.finally
Реактивный ключ реквизита