反应:重新加载页面后不再获取数据

时间:2021-07-25 12:01:08

标签: javascript reactjs typescript api fetch

我在 useEffect() 中成功获取了电影的数据。但是,当页面重新加载时,之前获取的数据会消失,并且会在控制台中打印出 404 错误。如何预防?

这是重新加载的组件:

import {useState, useEffect, useContext} from "react";
import Topbar from '../Header/Topbar';
import { fetchSelectedMovie } from "../../services/movies.service";
import {Grid, Card, CardMedia} 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 [movie, setMovie] = useState<Movie>(
    {
      id: 0,
      title: '',
      vote_average: 0,
      overview: '',
      poster_path: noImage,
      release_date: '',
      budget: 0,
      revenue: 0,
      genres: [],
    }
  );
  const [movieImg, setMovieImg] = useState<string>(noImage);

  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>
        </Grid>
    </>
  );
}

export default MoviePage;

Movie id selectedMovie 使用 React Context 从 App.tsx 组件获取,默认值 = 0:const [selectedMovie, setSelectedMovie] = useState(0);

这是调用 API 以获取数据:

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 {};
    });
}

使用的反应上下文:

import React from "react";
import { Movie } from "./movies.service";

export const MoviesContext = React.createContext<{
    movies: Movie[];
    updateMovies: Function;
    selectedMovie: number;
    setSelectedMovie: (value: number) => void;
  }>({
    movies: [],
    updateMovies: Function,
    selectedMovie: 0,
    setSelectedMovie: () => {},
  });

这些是我收到的 404 错误: enter image description here

非常感谢!

1 个答案:

答案 0 :(得分:1)

重新加载页面后,selectedMovie 是否存在于 MoviePage 组件中?它可能不存在,并且您将未定义的值传递给 API,从而导致 404 错误。

一个好主意是仅当 selectedMovie 存在时才渲染 MoviePage,或者在 useEffect 中添加一个检查以仅在定义 selectedMovie 时调用 API。

您能否还添加上下文和 API 调用代码,以便我们看看它的作用? 查看您的屏幕截图,您似乎向 API 传递了一个等于 0 的 ID,而具有此类 ID 的电影可能不存在,因此会出现 404 错误。

编辑:那么这可能只是 API 无法找到 ID 为 0 的电影的问题。在这种情况下,404 错误表明服务器无法找到您要搜索的内容.您可以阅读有关错误代码 here 的更多信息。

为了处理此类错误,您可以在响应中查找错误代码并根据需要进行处理:

fetch('/movies/${movieID}').then(function(response) {
  if (response.status === 404) {
    console.log("Server couldn't find such movie!");
  }
})