I'm getting images via an API that is fetched in a useEffect hook.
I want to store a random image into an object array and display it immediately when loading the side.
The problem is the useEffect hook is executed after rendering so the function which gets the random image throws an error.
const [allImages, setAllImages] = useState([]);
useEffect(() => {
fetch("https://api.imgflip.com/get_memes")
.then((response) => response.json()
.then((data) => setAllImages(data.data.memes));
}, []);
const [memes, setMemes] = useState([
{ img: getRandomImg() },
]);
function getRandomImg() {
const randomIndex = Math.floor(Math.random() * allImages.length);
console.log("3");
return allImages[randomIndex].url;
}
First thought was to just return the getRandomImg function if there are no images but nothing is displayed then.
function getRandomImg() {
if (allImages.length === 0) return;
const randomIndex = Math.floor(Math.random() * allImages.length);
console.log("3");
return allImages[randomIndex].url;
}
I found a solution that works by adding another useEffect with a dependencie on allImages.
useEffect(() => {
fetch("https://api.imgflip.com/get_memes")
.then((response) => response.json())
.then((data) => setAllImages(data.data.memes));
}, []);
useEffect(() => {
if (allImages.length > 0) {
addImage();
}
}, [allImages]);
const [memes, setMemes] = useState([]);
function getRandomImg() {
const randomIndex = Math.floor(Math.random() * allImages.length);
console.log("3");
return allImages[randomIndex].url;
}
const addImage = () => {
setMemes((prevMemes) => [
...prevMemes,
{
img: getRandomImg(),
},
]);
};
But this seems more like a workaround and this is sometimes adding two pictures instead of one.
Is there any way to get this to work?