In my App, I am implementing Product Listing page which lists out the products on the listing page. I am looking to integrate some good practices based on this post – https://dev.to/vyan/using-async-functions-in-useeffect-best-practices-and-pitfalls-o75 but instead of let
I am using ref
to track.
I am getting the list of products in the console message but it displays no list in the UI. When I comment the – isMounted.current = false;
line in my cleanup function then only it displays the list. Let me know what I am doing wrong here with the cleanup ?
App.jsx –
import { useEffect, useRef, useState } from "react";
import ProductsList from "./components/ProductsList";
import "./styles.css";
export default function App() {
const isMounted = useRef(true);
const [products, setProducts] = useState([]);
const fetchData = async () => {
try {
const data = await fetch("https://dummyjson.com/products");
const { products = [] } = await data.json();
console.log(products); // It shown as Array of object in the console
if (isMounted.current) {
setProducts(products);
}
} catch (error) {
if (isMounted.current) {
console.error("Error fetching data: ", error);
}
}
};
useEffect(() => {
fetchData();
return () => {
isMounted.current = false; // Cleanup on unmount
};
}, []);
return (
<div className="App">
<h1>Product Listing Page</h1>
{products.length ? <ProductsList products={products} /> : null}
</div>
);
}
ProductsList.jsx –
const ProductsList = ({ products }) => {
return (
<div className="products-list">
{products.map((product) => {
return (
<div className="product" key={product.id}>
<div className="max-w-sm rounded overflow-hidden shadow-lg">
<img
className="w-full"
src={product.thumbnail}
alt={product.thumbnail}
/>
<div className="px-6 py-4">
<div className="font-bold text-xl mb-2">{product.title}</div>
<p className="text-gray-700 text-base">{product.description}</p>
</div>
<div className="px-6 pt-4 pb-2">
{product.tags.map((tag, index) => (
<span
key={index}
className="inline-block bg-gray-200 rounded-full px-3 py-1 text-sm font-semibold text-gray-700 mr-2 mb-2"
>
#{tag}
</span>
))}
</div>
</div>
</div>
);
})}
</div>
);
};
export default ProductsList;