Reputation: 409
Trying to render an API call which returns an array of products.
How to show loading message on products render. (Currently the "loading" message is not being displayed)
useGetProducts.js
import { useEffect, useState } from "react";
import axios from "axios";
const useGetProducts = (API) => {
const [products, setProducts] = useState(null);
const [error, setError] = useState("");
const [loaded, setLoaded] = useState(false);
useEffect(() => {
(async () => {
try {
async function fetchData() {
const response = await axios(API);
setProducts(response.data)
}
fetchData();
} catch (error) {
setError(error.message);
} finally {
setLoaded(true);
}
})();
}, []);
return { products, error, loaded };
};
export default useGetProducts
ProductList.js
import React from "react";
import ProductItem from "./ProductItem";
import useGetProducts from "../hooks/useGetProducts";
import { Link } from "react-router-dom";
import { API } from '../constants/constants';
const ProductList = () => {
const data = useGetProducts(`${API}?limit=9&offset=0`);
return (
<section className="theme-section">
{data.loaded ?
<>
{data.products && data.products.map((product) => (
<div key={product.id}>
<ProductItem product={product} />
<Link to={`/product/${product.id}`}>ver detalle</Link>
<br /><br />
<hr />
</div>
))}
</>
: "loading"
}
</section>
)
}
export default ProductList;
Currently the message is not being displayed
Upvotes: 2
Views: 715
Reputation: 2010
set your loaded
state to false
when you enter in fetchData
function and in finally
method, update loaded
state to true
.
useEffect(() => {
(async () => {
try {
async function fetchData() {
setLoaded(false);
const response = await axios(API);
setProducts(response.data);
}
fetchData();
} catch (error) {
setError(error.message);
} finally {
setLoaded(true);
}
})();
}, []);
Upvotes: 1
Reputation: 12010
What is happening here is that you're calling fetchData
without waiting for it, which is immediately setting loaded
to true.
I don't think there is a need for the fetchData
function here, so either remove it or await it:
const [products, setProducts] = useState(null);
const [error, setError] = useState("");
const [loaded, setLoaded] = useState(false);
useEffect(() => {
(async () => {
const response = await axios(API);
setProducts(response.data)
} catch (error) {
setError(error.message);
} finally {
setLoaded(true);
}
})();
}, []);
Upvotes: 2