I am trying to render a component when certain states are triggered that are passed through Context API but after adding a console.log
everywhere I noticed that the problem was with my useEffect()
not being run and I don't know why:
interface ImageResponse {
message: string;
}
interface ImageProps {
breed: string;
opened: boolean;
}
const BreedImageGenerator: FunctionComponent<ImageProps> = (opened, breed) => {
const [randomImages, setRandomImage] = useState<ImageResponse[]>([]);
useEffect(() => {
const fetchRandomImages = async () => {
const res: AxiosResponse = await axios.get<ImageResponse>(
`https://dog.ceo/api/breed/${breed}/images/random/4`
);
setRandomImage(res.data.message);
console.log(randomImages);
};
}, []);
return (
<Box
id="randomBreedImage">
<Box>
<ImageList sx={{ width: 500, height: 450 }}>
<ImageListItem key="Subheader" cols={2}>
<ListSubheader component="div">{breed}</ListSubheader>
</ImageListItem>
{randomImages &&
randomImages.map((randomImage) => (
<ImageListItem key={randomImage}>
<img
src={randomImage}
/>
</ImageListItem>
))}
</ImageList>
</Box>
</Box>
);
};
export default BreedImageGenerator;
I am sure that every prop is being passed correctly and as you can see there's a console log
inside my useEffect()
as well, but no luck. Any ideas?
I've tried even deleting everything from inside the useEffect()
and keeping a console.log
but nothing is being logged which is really strange because when I 'm calling the component (after those conditions that I mentioned earlier) all of the conditions evaluate to true.
This is where my component is being called:
<Grid item md="auto" xl={3.5}>
{breeds &&
breeds.map((breed) => {
clickedBreed[breed.key] && isOpened && (
<BreedImageGenerator
breed={breed.key}
opened={isOpened}
key={breed.key}
/>
);
})}
</Grid>
And I know that all of these evaluate to true because when I replaced the <BreedImageGenerator/>
with a console.log()
, it was logging.
Also, doing this:
const [randomImages, setRandomImage] = useState<ImageResponse[]>([]);
useEffect(() => {
const fetchRandomImages = async () => {
const res: AxiosResponse = await axios.get<ImageResponse[]>(
`https://dog.ceo/api/breed/${breed}/images/random/4`
);
setRandomImage(res.data.message);
};
fetchRandomImages();
console.log(randomImages);
}, []);
changes nothing, my component is still not getting rendered.
CodePudding user response:
After you created the fetchRandomImages()
function you need to call it.
E.g.
useEffect(() => {
const fetchRandomImages = async () => {
const res: AxiosResponse = await axios.get<ImageResponse>(
`https://dog.ceo/api/breed/${breed}/images/random/4`
);
setRandomImage(res.data.message);
console.log(randomImages); //Do not call console.log right after setting state as it's still not ready.
};
fetchRandomImages() // You need to call the function here.
}, []);
useEffect(() => {
console.log(randomImages) //use it here.
},[randomImages]) //this useEffect calls when randomImages changed.
CodePudding user response:
Declaring function inside useEffect does not mean it will execute, you have to execute by typing fetchRandomImages()
CodePudding user response:
Okay, I just fixed it, so I deleted the opened
props as a test because I read somewhere that functional components only accept one prop passed to them (no idea why), and added the breed
prop inside brackets, which I was avoiding because, since I am in typescript I was getting an error about it (as usual).
Also, ALL of the comments helped, so thank you!