首页 > 解决方案 > 第二次调用 useEffect() 时页面崩溃

问题描述

useContext()用来将所选电影的想法传递给 React 组件。我正在使用 useEffect()第一次渲染 React 页面(组件)时获取有关该电影的数据,并且此方法有效。

但是,如果重新加载页面,它会崩溃并显示错误“TypeError: Cannot read property 'map' of undefined”。

在此处输入图像描述

电影页面.tsx

import {useState, useEffect, useContext} from "react";
import Topbar from '../Header/Topbar';
import { fetchSelectedMovie } from "../../services/movies.service";
import {Grid, Card, CardMedia, Button} from '@material-ui/core';
import noImage from '../../images/no-image-available.png';
import { MoviesContext } from "../../services/context";
import './Pages.css';
const posterBaseUrl = "https://image.tmdb.org/t/p/w300";
interface Genre {
  id: number;
  name: string;
}
interface Movie {
  id: number;
  title: string;
  vote_average: number;
  overview: string;
  poster_path?: string;
  release_date: string;
  budget: number;
  revenue: number;
  genres: Genre[];
}

const MoviePage = (props: any) => {

  const { selectedMovie } = useContext(MoviesContext);

  const [movieImg, setMovieImg] = useState<string>(noImage);
  const [movie, setMovie] = useState<Movie>(
    {
      id: 0,
      title: '',
      vote_average: 0,
      overview: '',
      poster_path: noImage,
      release_date: '',
      budget: 0,
      revenue: 0,
      genres: [],
    }
  );

  useEffect(() => {
    const callAPI = async () => {
      const fetchedMovieInfo = await fetchSelectedMovie(Number(selectedMovie));
      setMovie(fetchedMovieInfo);
      setMovieImg(posterBaseUrl+fetchedMovieInfo.poster_path);
    }

    callAPI();
  }, [selectedMovie]);

  return (
    <>
      <Topbar></Topbar>
      <Grid container spacing={2} className="container-movie-page">
        <Grid item xs={6} sm={3}>
          <Card className="card">
            <CardMedia
              component="img"
              alt={"Poster of " + movie.title}
              image={movieImg}
              title={movie.title}
            />
          </Card>
        </Grid>
        <Grid item xs={6} sm={9} className="align-left">
          <h1 className="title">
            {movie.title}
          </h1>
          <div className="content">
            <span className="rating-container">
              {movie.vote_average}
            </span>
            <div>
              {movie.release_date}
            </div>
            <p className="content-main-paragraph">
              {movie.overview}
            </p>
            <p>
              Genres:&nbsp;
                {movie.genres.map((genre, i) => (
                  <span key={i}>
                    {genre.name},&nbsp;
                  </span>
                ))}
            </p>
            <p>
              Budget: ${movie.budget}
            </p>
            <p>
              Revenue: ${movie.revenue}
            </p>
            <Button 
              variant="contained" 
              color="primary" 
              href="#">
               sth
            </Button>
          </div>
        </Grid>
        <Grid item xs={12}>
          CAST HERE (carrousel to scroll horiz)
        </Grid>
      </Grid>
    </>
  );
}

export default MoviePage;

电影服务.tsx

export async function fetchSelectedMovie (currentMovieId: number ) {
  return await fetch(
    `${movieApiBaseUrl}/movie/${currentMovieId}?api_key=${process.env.REACT_APP_API_KEY}`
  )
    .then((res) => res.json())
    .then((body) => {return body})
    .catch(() => {
        return {};
    });
}

你知道有什么问题吗?

标签: javascriptreactjstypescriptapifetch

解决方案


推荐阅读