简体   繁体   English

如何在从 API (React) 获取数据时加载微调器

[英]How can I load a spinner while fetching data from API (React)

I am using react useParams to show a singleMovie (details).我正在使用 react useParams 来显示单个电影(详细信息)。 I have also a condition that if there is no picture (in the API) to show a stock picture.我还有一个条件,如果没有图片(在 API 中)来显示库存图片。 However, the problem is that when I access the single movie detail the stock photo shows first then the API picture.但是,问题是当我访问单个电影详细信息时,库存照片首先显示,然后是 API 图片。

How can I fix this or add a spinner so that I dont see the stock photo first.我该如何解决这个问题或添加一个微调器,这样我就不会先看到库存照片。

import React from 'react'
import { Link, useParams } from 'react-router-dom';
import { useState, useEffect } from 'react';
import { API_KEY, IMAGE_BASE_URL } from '../config';
import NoCover from '../img/no-cover.jpg'





const SingleMovie = () => {
  const { movieId } = useParams();
  const MOVIE_API = `https://api.themoviedb.org/3/movie/${movieId}?api_key=${API_KEY}&language=en-US`;
  //useState
  const [movieDetails, setMovieDetails] = useState([])
  //functions
  const getMovieDetails = async (API) => {
    const response = await fetch(API)
    const data = await response.json()
    //console.log(data);
    setMovieDetails(data)
    
  }
  //useEffect
  useEffect(() => {
    getMovieDetails(MOVIE_API)
  }, [MOVIE_API])
  
  const { title, poster_path } = movieDetails
  
  return (
    <>
      <h1>{title}</h1>
      <div>
        {poster_path ? (<img src={`${IMAGE_BASE_URL}${poster_path}`} alt={title} />) : (<img src={NoCover} alt={title} />)}
      </div>
      <Link to="/">Go Back</Link>
      
      </>
    
    );
}

export default SingleMovie

Hey what you can do is create a boolean useState to display a Loading... while getting the data.嘿,你可以做的是创建一个 boolean useState来显示Loading...同时获取数据。 Like this:像这样:

Add:添加:

const [loading, setLoading] = useState(false);

The function that gets the data, there I added a try catch so also you see if there is an error.获取数据的 function 在那里我添加了一个try catch所以你也看看是否有错误。

const getMovieDetails = async (API) => {
    setLoading(true);
    try {
      const response = await fetch(API);
      const data = await response.json();
      //console.log(data);
      setMovieDetails(data);
    } catch (error) {
      console.log('Error', error);
    } finally {
      setLoading(false);
    }
  };

And then you can add this ternary in the return:然后你可以在返回中添加这个三元:

{!loading ? (
        <div>
          {poster_path ? (
            <img src={`${IMAGE_BASE_URL}${poster_path}`} alt={title} />
          ) : (
            <img src={NoCover} alt={title} />
          )}
        </div>
      ) : (
        'Loading...'
      )}

Where I added the text Loading... , you can add a spinner component or whatever you want!在我添加文本Loading...的地方,您可以添加微调器组件或任何您想要的!

define a state variable loading can be solved定义一个 state 变量loading即可解决

Try out this code试试这个代码

import React from 'react'
import { Link, useParams } from 'react-router-dom';
import { useState, useEffect } from 'react';
import { API_KEY, IMAGE_BASE_URL } from '../config';
import NoCover from '../img/no-cover.jpg'





const SingleMovie = () => {
  const { movieId } = useParams();
  const MOVIE_API = `https://api.themoviedb.org/3/movie/${movieId}?api_key=${API_KEY}&language=en-US`;
  //useState
  const [movieDetails, setMovieDetails] = useState([])
  const [loading, setLoading] = React.useState(true); // +++
  //functions
  const getMovieDetails = async (API) => {
    const response = await fetch(API)
    if(response.ok){ // +++
        const data = await response.json()
       //console.log(data);
       setMovieDetails(data);
       setLoading(false); // +++
    } // +++
    
  }
  //useEffect
  useEffect(() => {
    getMovieDetails(MOVIE_API)
  }, [MOVIE_API])
  
  const { title, poster_path } = movieDetails
  
  return (
    <>
      <h1>{title}</h1>
      // +++
      {loading ? "spinner" : (<>
      <div>
        {poster_path ? (<img src={`${IMAGE_BASE_URL}${poster_path}`} alt={title} />) : (<img src={NoCover} alt={title} />)}
      </div>
      </>)}
      // +++
      <Link to="/">Go Back</Link>
      
      </>
    
    );
}

export default SingleMovie

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM