Reputation: 41
I'm trying to render a list of favorite movies based on signed-in user's list.The flow is following:
Unfortunately I was able to update the array of objects only via push, which resulted in calling setContent(items)
for every item which means that content
variable exists even with 1st iteration, leaving the option to render the "trending" div
as value is truth not rendering full content.
How can I either refactor the useEffect
? Change the render conditions for "Trending" to be sure, that all values in content
var are finished updating via API?
const Favorite = () => {
const { user } = useAuthContext();
const { documents: movies } = useCollection("favMovies", ["uid", "==", user.uid]); // only fetch movies for loged user
const [page, setPage] = useState(1);
const [content, setContent] = useState([]);
const [numOfPages, setNumOfPages] = useState();
useEffect(() => {
const items = [];
movies &&
movies.forEach(async (movie) => {
try {
const response = await axios.get(
`https://api.themoviedb.org/3/${movie.mediaType}/${movie.id}?api_key=${process.env.REACT_APP_API_KEY}&language=en-US`
);
items.push(response.data);
setContent(items);
} catch (error) {
console.error(error);
}
});
}, [movies]);
return (
<div>
<span className="pageTitle">Trending</span>
<div className="trending">
{content &&
content.map((con) => (
<SingleContent
key={con.id}
id={con.id}
poster={con.poster_path}
title={con.title || con.name}
date={con.first_air_date || con.release_date}
mediaType={con.media_type}
voteAverage={con.vote_average}
/>
))}
</div>
<CustomPagination setPage={setPage} />
</div>
);
};
export default Favorite;
Upvotes: 2
Views: 79
Reputation: 45913
You can overcome your problem by using Promise.all()
. For that change your useEffect
code to:
useEffect(() => {
const fectchMovies = async () => {
if (!movies) return;
try {
const promises = movies.map((movie) =>
axios.get(
`https://api.themoviedb.org/3/${movie.mediaType}/${movie.id}?api_key=${process.env.REACT_APP_API_KEY}&language=en-US`
)
);
const content = await Promise.all(promises);
setContent(content.map(c => c.data));
} catch (error) {
console.error(error);
}
};
fectchMovies();
}, [movies]);
Upvotes: 1