Using contentful as my CMS and retrieving my content using code below
const ProductsGrid = () => {
let imageURL;
client.getEntries().then(function (entries) {
entries.items.forEach(function (entry) {
imageURL = entry.fields.image.fields.file.url
console.log(imageURL)
}
)
})
This works and i can see my imageURL’s in console
//images.ctfassets.net/zpu537igy6hd/10jOjKpdTYAYRVc197KlAs/60910da04dceab7acda47c042261776e/397526804_263713576623932_2944288645324919698_n.jpg
ProductsGrid.jsx:17 //images.ctfassets.net/zpu537igy6hd/2fat5G5gnOIT00YAdoSVZg/ea3f8c44b62cf977bc8a0d5b3e4eeea7/397492507_267421149586508_6988846565487064728_n.jpg
The problem is I cannot get this imageURL to render out in my react project
return (
<figure className='px-4 pt-4'>
<img
src={imageURL}
alt={title}
className='rounded-xl h-64 md:h-48 w-full object-cover'
/>
</figure>
imageURL is returning undefined instead of my URL links.
Am I resolving my Promises incorrectly?
Thanks
4
A state is a must.
Since the asynchronous call to get the url will complete later than the component is rendered, the url at the time of initial render will be undefined in this case. Now the requirement is that we need to have another render as soon as the url has been fetched. Therefore in order to trigger a new render, there would need a state. The url fetched will be set against this state, and this change in state will cause another render and the desired output.
Please see below two sets of sample codes.
a. Without a state
export default function App() {
let url;
new Promise((resolve) => {
setTimeout(() => resolve('http://someurl'), 1000);
}).then((newurl) => (url = newurl));
return <>{url ? url : 'no url'}</>;
}
Test run
On loading the App
b. With a state
import { useState } from 'react';
export default function App() {
const [url, setURL] = useState();
new Promise((resolve) => {
setTimeout(() => resolve('http://someurl'), 1000);
}).then((url) => setURL(url));
return <>{url ? url : 'no url'}</>;
}
Test run
After the set timeout of 1s.