I'm creating a simple movie app with moviedb. I have successfully retrieved the most popular 20 movies and put them in the app state:
constructor(props) {
super(props);
this.state = {
movieInfo: [],
}
}
componentDidMount() {
this.getMovies();
}
getMovies = async () => {
await axios.get('https://api.themoviedb.org/3/movie/popular?api_key=94d4ad026c5009bdaf4aecb8989dfa07')
.then(res => this.setState({ movieInfo: res.data.results }))
}
I know the array was retrieved correctly because when I look at the React components in Chrome dev tools I see what I want:
Then in the render part of the App I want to pass the first element in the array to a component called Movie, which will then display some info about the movie:
return (
<div>
<Movie movie={this.state.movieInfo[0]} />
</div>
);
}
I know the movie component is getting this info correctly because I see the object representing the first movie in the Movie component props:
My Movie function looks like this:
return (
<div>
<h1>{props.movie.original_title}</h1>
<p>{props.movie.overview}</p>
</div>
)
}
The first time I compile it this works and I see the info I want:
Rendered App with Movie component
But incredibly, when I refresh the page I see the error message
TypeError: Cannot read properties of undefined (reading 'original_title')
How is it possible that the App will correctly pass on the info to Movie and will display it correctly once, but as soon as I refresh the page somehow it's undefined?
Thanks in advance for the help, JD
CodePudding user response:
I assume that you don't get an error when you are developing and changing code. When you save your code Hot reloading only changes parts that changed.
This means that if your app loads data and populates this.state.movieInfo
with an array from BE, and your save you code, it Hot reloads and you get new data. So, this.state.movieInfo[0]
is always filled with data.
When you refresh your app, it just resets to an empty array as you put it there in the constructor
.
Solution is to always check if there is that first element in array before rendering the Movie
component:
return (
<div>
{this.state.movieInfo[0] ? <Movie movie={this.state.movieInfo[0]} /> : null}
</div>
);
CodePudding user response:
You may need to also use componentDidUpdate() with componentDidMount():
componentDidMount() {
this.getMovies();
}
componentDidUpdate() {
this.getMovies();
}
CodePudding user response:
when the page reloads init state is an empty array. you have to check the array has an item to render or not.
return (
<div>
{this.state.movieInfo && this.state.movieInfo.length>0 && (<Movie
movie={this.state.movieInfo[0]} />)}
</div>
);