Reputation: 77
For some reason, the loading
state doesn't change when I'm using this method to fetch from the API.
How to display "Loading..." while the call is running.
const [product, setProduct] = useState({});
const [loading, setLoading] = useState(false);
const productId = 1;
const fetchProduct = () => {
setLoading(true);
//here commerce is my api, so i fetched the product details and set it to the product state
commerce.products.retrieve(productId).then(data => setProduct(data));
setLoading(false);
}
useEffect(() => {
fetchProduct();
})
if (loading) {
return (
<span>Loading...</span>
)
}
return (
<h1>{product.name}</h1>
)
Upvotes: 1
Views: 8503
Reputation: 944294
Forget about loading
.
You can infer if the data is loading or not from the value of product
.
const Component = () => {
const [product, setProduct] = useState(null);
useEffect(() => {
const getProducts = async () => {
const data = await commerce.products.retrieve(productId)
setProduct(data);
};
getProducts();
}, []);
if (product === null) {
return <span>Loading...</span>;
}
return <h1>{product.name}</h1>;
}
If you really wanted to use a separate loading variable then you would have it default to true
and set it to false
at the same time you give a value to product
.
Upvotes: 0
Reputation: 311
I think there's two way for doing it corresponding of your code.
First, this one:
const [isLoading, setIsLoading] = useState(false);
const handleFetch = () => {
setIsLoading(true);
someApiCall().then((r) => {
setIsLoading(false);
});
};
Or
const [isLoading, setIsLoading] = useState(false);
const handleFetch = async () => {
setIsLoading(true);
await someApiCall();
setIsLoading(false);
};
Upvotes: 1
Reputation: 179
you didn't use async await at all but if you donn't wana use async await then u should use following
const fetchProduct = () => {
setLoading(true);
//here commerce is my api, so i fetched the product details and set it to the product state
commerce.products.retrieve(productId).then(data => {
setProduct(data);
setLoading(false);
}).catch(() => {
setLoading(false);
})
}
Upvotes: 0
Reputation: 151
You have to set the complete state inside the promise result just after retrive the products
const fetchProduct = () => {
setLoading(true);
commerce.products.retrieve(productId)
.then(data => {
setProduct(data)
//HERE
setLoading(false);
});
}
Upvotes: 1