I'm having trouble passing my props through in React and rendering them on my page. I want to map through my movies variable from my App.js pass the props of movie (Title, Poster, Price} to my MovieComponent.js so I can render them on the page.
function App() {
const [filmWorld, setFilmWorld] = useState([]);
const [cinemaWorld, setCinemaWorld] = useState([]);
useEffect(() => {
const theaters = ["cinema", "film"];
theaters.forEach((theater) => {
async function getTheater() {
const data = await api.getMoviesData(theater);
if (data.Provider === "Film World") {
setFilmWorld(data);
} else {
setCinemaWorld(data);
}
}
getTheater();
});
}, []);
const movies = useMemo(() => {
if (!filmWorld.Provider) return [];
return filmWorld.Movies.map((movie, index) => ({
...movie,
cinemaWorldPrice:
cinemaWorld.Provider && cinemaWorld.Movies[index]?.Price,
}));
}, [filmWorld, cinemaWorld]);
return (
<Container>
<Header>
<AppName>
<MovieImage src={movieicon1} />
Prince's Theatre
</AppName>
</Header>
<MovieListContainer>
{movies.map((movie, index) => (
<MovieComponent key={index} movie={movie} />
))}
<MovieComponent />
</MovieListContainer>
</Container>
);
}
export default App;
originally I had all the code underneath function App() { to return in my MovieComponent and could render in the movie component.
This is my Movie component code:
const MovieComponent = (props) => {
const { Poster, Price, Title } = props.movie;
return (
<MovieContainer>
<CoverImage src={Poster} alt="" />
<MovieName>{Title}</MovieName>
<InfoColumn>
<MovieInfo>FilmWorld: ${Price}</MovieInfo>
<MovieInfo>CinemaWorld: ${Price}</MovieInfo>
</InfoColumn>
</MovieContainer>
);
};
export default MovieComponent;
The last working code I had was when the functions and map were in my MovieComponent file this is a copy of the old working code:
const MovieComponent = () => {
const [filmWorld, setFilmWorld] = useState([]);
const [cinemaWorld, setCinemaWorld] = useState([]);
useEffect(() => {
const theaters = ["cinema", "film"];
theaters.forEach((theater) => {
async function getTheater() {
const data = await api.getMoviesData(theater);
if (data.Provider === "Film World") {
setFilmWorld(data);
} else {
setCinemaWorld(data);
}
}
getTheater();
});
}, []);
const movies = useMemo(() => {
if (!filmWorld.Provider) return [];
return filmWorld.Movies.map((movie, index) => ({
...movie,
cinemaWorldPrice:
cinemaWorld.Provider && cinemaWorld.Movies[index]?.Price,
}));
}, [filmWorld, cinemaWorld]);
return (
<MovieContainer>
{movies.map((movie, index) => (
<div className="movies" key={index}>
<MovieName>{movie.Title}</MovieName>
<CoverImage src={movie.Poster} alt={movie.Title} />
<InfoColumn>
<MovieInfo>
Filmworld Price: ${Number(movie.Price).toFixed(2)}
</MovieInfo>
<MovieInfo>
Cinemaworld Price: ${Number(movie.cinemaWorldPrice).toFixed(2)}
</MovieInfo>
</InfoColumn>
</div>
))}
</MovieContainer>
);
};
export default MovieComponent;
But this was effecting my stylings so I feel like if I call the functions and map in App and call the props in MovieComponent my app will render correctly again.
I'm receiving errors like this:
Uncaught TypeError: Cannot destructure property 'Poster' of 'props.movie' as it is undefined.
Why are you calling MovieComponent
a second time after the map function inside of your App.js
file without passing any props to it? try removing that and let me know if that helps.
Like this:
function App() {
const [filmWorld, setFilmWorld] = useState([]);
const [cinemaWorld, setCinemaWorld] = useState([]);
useEffect(() => {
const theaters = ["cinema", "film"];
theaters.forEach((theater) => {
async function getTheater() {
const data = await api.getMoviesData(theater);
if (data.Provider === "Film World") {
setFilmWorld(data);
} else {
setCinemaWorld(data);
}
}
getTheater();
});
}, []);
const movies = useMemo(() => {
if (!filmWorld.Provider) return [];
return filmWorld.Movies.map((movie, index) => ({
...movie,
cinemaWorldPrice:
cinemaWorld.Provider && cinemaWorld.Movies[index]?.Price,
}));
}, [filmWorld, cinemaWorld]);
return (
<Container>
<Header>
<AppName>
<MovieImage src={movieicon1} />
Prince's Theatre
</AppName>
</Header>
<MovieListContainer>
{movies.map((movie, index) => (
<MovieComponent key={index} movie={movie} />
))}
</MovieListContainer>
</Container>
);
}
export default App;