Skip to content
Advertisement

React component retrieves props just once, goes undefined when refreshed

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:

Screen cap of App state

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:

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

Advertisement

Answer

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>
);
User contributions licensed under: CC BY-SA
8 People found this is helpful
Advertisement