Reputation: 693
I have code like this below and my question is what can I do to get the products fetched before the components are rendered? I mean in my Panel component I have a .map function which shows an error "Cannot read property 'map' of undefined" because products were not fetched quickly enough.
const Announcments = () => {
const [announcements, setAnnouncement] = useState([]);
useEffect(() => {
const getProducts = async () => {
const res = await fetch("http://localhost:8000/api/products", {
method: "GET",
});
const data = await res.json();
await setAnnouncement(data);
};
getProducts();
}, []);
return (
<div className="announcments">
<TopNav results={announcements.length} />
<Panel announcements={announcements} />
<div className="down-pages-list">
<PagesList />
</div>
</div>
);
};
.map function:
{announcements.results.map((announcement) => (
<SingleAnnoun
price={announcement.price}
title={announcement.name}
photo={getPhoto(announcement.images[0].file_name)}
/>
))}
Upvotes: 1
Views: 53
Reputation: 202638
The issue here isn't that "products were not fetched quickly enough" but rather that your initial state doesn't match what you are attempting to render on the initial render. I.e. announcements
is initially an empty array ([]
) but you are attempting to map announcements.results
which is obviously undefined.
Use valid initial state so there is something to initially render.
const [announcements, setAnnouncement] = useState({ results: [] });
Now announcements.results
is defined and mappable.
This also assumes, of course, that your setAnnouncement(data);
state update is also correct. i.e. that your JSON data
is an object with a results
property that is an array.
BTW, setAnnouncement
is a synchronous function so there is nothing to await
for.
Upvotes: 1